首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析

  • 23-09-22 19:21
  • 3258
  • 6647
blog.csdn.net

一、 引言
在《第7.23节 Python使用property函数定义属性简化属性访问的代码实现》和《第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解》中介绍了两种设置属性访问方法,通过设置可以在相关属性访问时调用对应的方法执行访问,支持属性简单访问(如对象名.属性名、赋值语句)、或者为了控制访问逻辑使用的。那么property函数其中的fget、@property装饰器的getter之间的关系是怎样的呢?下面我们通过案例来进行分析。

二、 案例

  1. 案例说明:
    本案例定义类Car,其中有二个实例变量power、totaldistance、三个实例方法(构造方法、__ getattribute__方法、gettotaldistance方法)、一个装饰器和一个property函数定义属性变量语句。
    在__ getattribute__方法中将所有访问实例属性的属性名输出,并调用父类object类的__ getattribute__方法返回真正的数据。
    装饰器将实例变量power定义为carpower属性输出,虽然二者的值是一样的,但是两个不同的实例属性;
    property函数定义了totaldist属性,该属性输出的是实例变量totaldistance的值,二者值相同但实际上也是不同实例变量。然后我们执行totaldist和carpower的读取,看看输出是怎样的?
  2. 案例代码
>>> class Car(): 
    def __init__(self, power):
        self.power = power
        self.totaldistance = 10
        
    def __getattribute__(self, properyname):
        print("In __getattribute__,you are getting  properyty: {}".format(properyname))
        return object.__getattribute__(self, properyname)  
    
    @property  
    def carpower(self): #定义carpower属性的getter只读装饰器函数
       print("execute carpower")
       return self.power
    
    def gettotaldistance(self):
        print("execute gettotaldistance")
        return self.totaldistance #定义property的fget函数
    totaldist = property(gettotaldistance,None,None,'车辆行驶总里程')  #定义totaldist属性

	      
>>> car = Car('汽油发动机')
>>> car.carpower  #获取装饰器@property 定义属性carpower
In __getattribute__,you are getting  properyty: carpower
execute carpower
In __getattribute__,you are getting  properyty: power
'汽油发动机'
>>> car.totaldist #获取内置函数property 定义属性totaldist 
In __getattribute__,you are getting  properyty: totaldist
execute gettotaldistance
In __getattribute__,you are getting  properyty: totaldistance
10
>>>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  1. 案例截屏
    在这里插入图片描述
  2. 案例说明
    通过以上案例可以看出,使用装饰器@property 或property函数定义的属性(下称”定义属性”)访问过程是这样的:
    1> 执行__ getattribute__方法去访问“定义属性”;
    2> 调用@property的getter 或property类型的fget去执行具体的访问方法;
    3> 访问方法访问具体实例变量数据,再次触发__ getattribute__方法返回真正的数据。

三、 总结
通过上述案例及分析, property的fget、@property装饰器getter两者是基本是相同的,只是两种不同的实现,为了描述方便,后面统称为“property的get方法”。
__getattribute__与“property的get方法”之间的异同点如下:

  1. 都能在对实例对象进行属性get时触发,但“property的get方法”只能针对一个“定义属性”,而__getattribute__能针对所有属性包括特殊变量进行触发,触发后参数中有具体属性名;
  2. “property的get方法”只能针对“定义属性”的实例变量,而__getattribute__还能针对实例方法;
  3. 两者在解释器使用dir、type、help访问属性时触发,只不过“property的get方法”只能针对“定义属性”触发,而__getattribute__针对实例方法和所有实例变量;
  4. “property的get方法”返回数据一般是对应方法直接访问实例(self.属性)变量,而__getattribute__不能直接访问实例(self.属性)变量,否则会触发递归调用,只能用父类的__getattribute__方法返回数据;
  5. “定义属性”由于是针对实例变量进行了查询或查询后经过运算返回的,因此它的访问首先会执行__getattribute__方法去访问“定义属性”的数据,然后该访问被定向到绑定的get方法,该get方法会再次触发__getattribute__方法去访问实际需要访问的实例变量,因此使用“property的get方法”去查询“定义属性”的数据时,肯定会触发至少两次__getattribute__方法的执行(次数需要看“property的get方法”去查询的实例变量有多少个);
  6. __getattribute__方法是截获所有通过“实例名.属性名”访问实例变量、类变量、实例方法的所有操作来控制对属性的访问,而“property的get方法”则是为了方便访问数据,提高代码的易读性而实施的属性和方法的绑定。

本节结合案例深入分析了__getattribute__方法与“property的get方法”的异同点,。
老猿Python,跟老猿学Python!
博客地址:http://iyenn.com/index/link?url=https://blog.csdn.net/LaoYuanPython

请大家多多支持,点赞、评论和加关注!谢谢!

文章知识点与官方知识档案匹配,可进一步学习相关知识
Python入门技能树高级教程函数333596 人正在系统学习中
老猿Python
微信公众号
专注Python相关语言、图像音视频处理、AI
注:本文转载自blog.csdn.net的LaoYuanPython的文章"https://blog.csdn.net/LaoYuanPython/article/details/96161370"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top