python __getattribute__、__getattr__、__setattr__详解
__getattribute__
官方文档中描述如下:

该方法可以拦截对对象属性的所有访问企图,当属性被访问时,自动调用该方法(只适用于新式类)。因此常用于实现一些访问某属性时执行一段代码的特性。
需要注意的是,正式由于它拦截对所有属性的访问(包括对__dict__的访问),在使用中要十分小心地避开无限循环的陷阱。在__getattribute__方法中访问当前实例的属性时,唯一安全的方式是使用基类(超类) 的方法__getattribute__(使用super)。例如:

通过上图中的代码示例可以看出,一旦实现了__getattribute__方法,所有通过对象访问的属性(包括类属性)都会被拦截,而直接通过类访问类属性则不会。
注意:当访问的属性不存在并重载(覆盖基类对某方法的默认实现)了__getattribute__方法时,该方法不会主动抛出AttributeError异常。上图中捕获的AttributeError异常,是由基类__getattribute__方法实现并抛出。
常见的错误用法示例:

在实现__getattribute__方法时访问对象自身的属性,程序陷入无限循环直到崩溃。
__getattr__
官方文档描述如下:

__getattr__方法的自动执行,需要满足两个条件:一是访问对象属性;二是触发AttributeError异常。代码示例如下:

上图中,调用不存在的job属性首先调用__getattribute__方法(如果该方法未定义,会调用基类的__getattribute__方法),触发AttributeError异常并自动捕获,然后才调用__getattr__方法。
错误用法示例如下:

重载了__getattribute__方法,却没有主动抛出AttributeError异常的机制,或者抛出一个其它类型的异常,__getattr__方法都不会执行。
__setattr__

试图给属性赋值时自动调用该方法,例如:

之所以会执行三次print函数,是因为在__init__方法中,对象A初始化时给属性name和age赋值时,触发了__setattr__方法。使用该方法是同样需要十分小心避免无限循环陷阱。
错误用法示例如下:

可以看出,在__setattr__方法中,不能直接给属性赋值,而通常的做法是使用__dict__魔法属性。__dict__属性是一个字典,所有的实例属性都存储在这个字典中,而修改__dict__字典中的键值对成员不会触发__setattr__方法,这里应注意与直接修改__dict__的值的区别。
注意:如果定义__setattr__方法的同时定义了__getattribute__方法,那么在修改__dict__字典中的键值对时,由于调用了self.__dict__属性,同样会触发__getattribute__方法,使用时应格外小心。代码示例如下:

上图示例代码中,每调用一次__setattr__就会调用一次__getattribute__。
注意赋值语句与属性调用的区别:self.__dict__ = {}是赋值语句,不会触发__getattribute__方法,但触发__setattr__方法;self.__dict__[name] = value语句,先调用self.__dict__属性,得到dict对象后再修改其成员,因此会触发__getattribute__方法。
以上。
python __getattribute__、__getattr__、__setattr__详解的更多相关文章
- python之OS模块详解
python之OS模块详解 ^_^,步入第二个模块世界----->OS 常见函数列表 os.sep:取代操作系统特定的路径分隔符 os.name:指示你正在使用的工作平台.比如对于Windows ...
- python之sys模块详解
python之sys模块详解 sys模块功能多,我们这里介绍一些比较实用的功能,相信你会喜欢的,和我一起走进python的模块吧! sys模块的常见函数列表 sys.argv: 实现从程序外部向程序传 ...
- python中threading模块详解(一)
python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...
- Python数据类型及其方法详解
Python数据类型及其方法详解 我们在学习编程语言的时候,都会遇到数据类型,这种看着很基础也不显眼的东西,却是很重要,本文介绍了python的数据类型,并就每种数据类型的方法作出了详细的描述,可供知 ...
- python引用和对象详解
python引用和对象详解 @[马克飞象] python中变量名和对象是分离的 例子 1: a = 1 这是一个简单的赋值语句,整数 1 为一个对象,a 是一个引用,利用赋值语句,引用a指向了对象1. ...
- Python中time模块详解
Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...
- Python 列表(List)操作方法详解
Python 列表(List)操作方法详解 这篇文章主要介绍了Python中列表(List)的详解操作方法,包含创建.访问.更新.删除.其它操作等,需要的朋友可以参考下 列表是Python中最基本 ...
- Python模块调用方式详解
Python模块调用方式详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其 ...
- python之模块datetime详解
# -*- coding: utf-8 -*- #python 27 #xiaodeng #python之模块datetime详解 import datetime #data=datetime.dat ...
- Python对Excel操作详解
Python对Excel操作详解 文档摘要: 本文档主要介绍如何通过python对office excel进行读写操作,使用了xlrd.xlwt和xlutils模块.另外还演示了如何通过Tcl ...
随机推荐
- 随机抽样问题(蓄水池问题Reservoir Sampling)
转自:孤影醉残阳 http://hi.baidu.com/siyupy/item/e4bb218fedf4a0864414cfad 随机抽样问题(蓄水池问题Reservoir Sampling) 随即 ...
- 4.4.4 无锁的对象引用:AtomicReference和AtomicStampedReference
AtomicReference 这个类和AtomicInteger非常类似,只是AtomicReference对应普通的对象引用,而AtomicInteger 它是对整数的封装,它的方法如下 对wea ...
- 阿里云OSS-web直传---在服务端c#签名,浏览器直传
OSS web直传---在服务端php签名,浏览器直传 本文:OSS web直传---在服务端c#签名,浏览器直传 其他语言的范例地址:https://help.aliyun.com/document ...
- C# GDI+绘图介绍
最近查阅网上资料,将GDI+的基本知识汇总如下: 一.基本的知识 GDI+:Graphics Device Interface Plus也就是图形设备接口,提供了各种丰富的图形图像处理功能; 在C#. ...
- SpringMVC的问题No mapping found for HTTP request with URI
做了一个屏蔽进数据库的操作: Applicaition.xml配置: <?xml version="1.0" encoding="UTF-8"?> ...
- java中的继承(is a )和组合(has a)
我们知道java语言有三大特性:封装,继承,多态 但是继承和封装却是一对有点矛盾的两个方面,怎么理解?? 我们想想:封装的目的是想让隐藏类中的属性和方法.但是在继承过程中,我们的子类肯定会继承父类的方 ...
- windows10个性化设置
任务栏DIY 日期显示样式 字体
- C++ 动态分配二维和三维数组
目的:熟悉c++动态内存分配 描述:使用c++程序定义动态数组类,使用new和delete操作符实现动态二维数组和三维数组的定义 //main.cpp //主程序类 #include <iost ...
- Git代码行统计命令集
统计某人的代码提交量,包括增加,删除: git log --author="$(git config --get user.name)" --pretty=tformat: --n ...
- java-设计模式汇总整理
最近,对各种模式做了一个整理,便于后续自用. 1.工厂模式 总结:很好理解,一个接口,2个类实现这个接口,那么可以用“接口 变量=new 接口实现类”的方式调用不同的实现类,调用方式直接使用接口的方法 ...