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 ...
随机推荐
- 基于CacheManager组件的缓存产品配置
一.Couchbase 使用CacheManager组件,在配置Couchbase缓存支持时,由于对配置节cache handle命名规则要求不了解,费了点时间查了源码才明白. section配置节 ...
- poj 2007 Scrambled Polygon
#include<stdio.h> #include<algorithm> using namespace std; #define Max 60 struct Point { ...
- functions函数插件的定义和使用
创建Smarty插件:在插件目录(plugins)里新建文件 类型.插件名.php文件,然后插件方法名字书写规范: smarty_类型_插件名([...]){}在模板(tpl文件)中调用插件时格式{插 ...
- java调.NET webapi时间戳报错问题
JAVA时间戳长度是13位,如:1294890876859 PHP .NET时间戳长度是10位, 如:1294890859 主要最后三位的不同,JAVA时间戳在.NETPHP中使用,去掉后三位,如:1 ...
- Ubuntu16 apt-get更换为阿里源
1.备份系统自带源 mv /etc/apt/sources.list /etc/apt/sources.list.bak 2.修改/etc/apt/sources.list文件 vim /etc/ap ...
- mysql链接错误:2003 can't connect to mysql server on 10038
出现这个错误原因是端口号不是3306. 打开D:\Program Files\MySQL\MySQL Server 5.5 \my.ini文件,当然还有其他的.ini的文件: [client] ...
- 优秀前端工程师必备: (总结) 清除原生ios按钮样式
写移动端的web开发时, 需要清除IOS本身的各种样式: 1.消除ios按钮原生样式, 给按钮加自定义样式: input[type="button"], input[type=&q ...
- 获取host信息
QT如果要进行网络编程首先需要在.pro”中添加如下代码: QT += network 在头文件中包含相关头文件: #include <QHostInfo> #include <QN ...
- android多lib库工程的自动批量构建--编写ant脚本
基本配置--build.properties 首先编写基本配置build.properties ,主要配置如下: android sdk所在目录 编译项目所使用的项目版本 Jdk所在目录 以及签名时, ...
- thinkjs 框架图