一、 引言

《第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. 案例说明

    通过以上案例可以看出,使用装饰器@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!

博客地址:https://blog.csdn.net/LaoYuanPython


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

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

  1. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...

  2. 第8.23节 Python中使用sort/sorted排序与“富比较”方法的关系分析

    一. 引言 <第8.21节 Python中__lt__.gt__等 "富比较"("rich comparison")方法用途探究>和<第8.2 ...

  3. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    一.生成器 1.什么是生成器? 在python中,一边循环一边计算的机制,称为生成器:generator. 2.生成器有什么优点? 1.节约内存.python在使用生成器时对延迟操作提供了支持.所谓延 ...

  4. 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类

    第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一.    引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...

  5. 第7.15节 Python中classmethod定义的类方法详解

    第7.15节  Python中classmethod定义的类方法详解 类中的方法,除了实例方法外,还有两种方法,分别是类方法和静态方法.本节介绍类方法的定义和使用. 一.    类方法的定义 在类中定 ...

  6. 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解

    第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一.    引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...

  7. 第7.22节 Python中使用super调用父类的方法

    第7.22节 Python中使用super调用父类的方法 前面章节很多地方都引入了super方法,这个方法就是访问超类这个类对象的.由于super方法的特殊性,本节单独谈一谈super方法. 一.su ...

  8. 第11.20节 Python 中正则表达式的扩展功能:后视断言、后视取反

    一. 引言 在<第11.19节 Python 中正则表达式的扩展功能:前视断言和前视取反>中老猿介绍了前视断言和前视取反,与二者对应的还有后视断言和后视取反. 二. (?<=-)后视 ...

  9. 第14.12节 Python中使用BeautifulSoup解析http报文:使用select方法快速定位内容

    一. 引言 在<第14.10节 Python中使用BeautifulSoup解析http报文:html标签相关属性的访问>和<第14.11节 Python中使用BeautifulSo ...

随机推荐

  1. C语言中宏的作用

    在C语言#define机制中包括了一个规定,与允许把参数替换到文本中,这种实现通常称为宏或宏定义.下面是宏的声明方式: #define      name(parameter-list)       ...

  2. 3.4 spring5源码系列--循环依赖的设计思想

    前面已经写了关于三篇循环依赖的文章, 这是一个总结篇 第一篇: 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 第二篇: 3.2spring源码系列----循环依赖源 ...

  3. Spider_基础总结7_爬虫基本模板(3个类)

    # 第四章内容--处理不同的网站布局: # 我们想在功能类似的网站上抓取类似内容时,往往这些网站的内容可能布局不一样(相同内容的标签可能不同),由于通常我们爬取的网站数量有限, # 我们没有必要去开发 ...

  4. IP 层收发报文简要剖析6--ip报文输出3 ip_push_pending_frames

    L4层的协议会把数据通过ip_append_data或ip_append_page把数据线放在缓冲区,然后再显示调用ip_push_pending_frames传送数据. 把数据放在缓冲区有两个优点, ...

  5. uboot——do_bootm

    do_bootm |----------根据参数得到 image的起始地址 |----------比较header的 magic_num 是否为 zImage | |是 | | zImage路线 | ...

  6. 掌握这些springboot的配置方式,让你工作效率翻个倍!

    springboot的多种配置方式 java配置主要靠java类和一些注解,比较常用的注解有: @Configuration :声明一个类作为配置类,代替xml文件 @Bean :声明在方法上,将方法 ...

  7. 建议收藏!超详细的JVM反射原理技术点总结

    反射定义 1,JAVA反射机制是在运行状态中 对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调用对象的方法的功能称 ...

  8. 了解 MySQL的数据行、行溢出机制吗?

    目录 一.行 有哪些格式? 二.紧凑的行格式长啥样? 三.MySQL单行能存多大体量的数据? 四.Compact格式是如何做到紧凑的? 五.什么是行溢出? 六.行 如何溢出? 七.思考一个问题 关注送 ...

  9. ABBYY FineReader如何将图片转换为Excel

    ABBYY FineReader的OCR文字识别功能很强大,不但可以将文件转换为文本文档或Word文档,也可以识别PDF文件或者图片上的表格,并且转换为Excel文件.下面我就为大家演示一下怎么用AB ...

  10. FL Studio乐理教程之调式音阶

    在我们使用FL制作音乐时,乐理是必不可少的制作基础,本篇教程将结合FL Studio为大家讲解基础乐理及在FL Studio20中的使用技巧. 添加一个乐器,打开Piano Roll(钢琴窗). 首先 ...