教程集 www.jiaochengji.com
教程集 >  Python编程  >  Python入门  >  正文 Python魔法方法之__getattr__和getattribute

Python魔法方法之__getattr__和getattribute

发布时间:2021-12-14   编辑:jiaochengji.com
教程集为您提供Python魔法方法之,,getattr,,和getattribute等资源,欢迎您收藏本站,我们将为您提供最新的Python魔法方法之,,getattr,,和getattribute资源

在Python中有这两个魔法方法容易让人混淆:__getattr__和getattribute。通常我们会定义__getattr__而从来不会定义getattribute,下面我们来看看这两个的区别。

__getattr__魔法方法

<pre class="brush:php;toolbar:false">class MyClass:     def __init__(self, x):         self.x = x     def __getattr__(self, item):         print('{}属性为找到!'.format(item))         return None >>> obj = MyClass(1) >>> obj.x 1 >>> obj.y y属性为找到! None</pre>

我们定义一个MyClass类,设置一个实例属性为x,值为1。obj为这个类的实例,获取obj.x返回1,而获取obj.y发现属性找不到,原因是obj的实例变量中不包含y,找不到某属性时会调用__getattr__方法。

**调用__getattr__详细过程如下:**

obj.attr

1.首先会在对象的实例属性中寻找,找不到执行第二步

2.来到对象所在的类中查找类属性,如果还找不到执行第三步

3.来到对象的继承链上寻找,如果还找不到执行第四步

4.调用obj.__getattr__方法,如果用户没有定义或者还是找不到,抛出AttributeError异常,属性查找失败!

<pre class="brush:php;toolbar:false">class MyClass:     def __init__(self, x):         self.x = x >>> obj = MyClass(1) >>> obj.y AttributeError: 'MyClass' object has no attribute 'a'</pre>

如上代码,没有定义__getattr__魔法方法,又找不到属性,就会抛出异常。

相关推荐:《Python视频教程》

__getattribute__魔法方法

当我们调用对象的属性时,首先会调用__getattribute__魔法方法。

<pre class="brush:php;toolbar:false">obj.x obj.__getattribute__(x)</pre>

如上代码,这两个代码其实是等价的。当__getattribute__查找失败,就会去调用__getattr__方法。

代码演示

<pre class="brush:php;toolbar:false">class MyClass:     def __init__(self, x):         self.x = x     def __getattribute__(self, item):         print('正在获取属性{}'.format(item))         return super(MyClass, self).__getattribute__(item) >>> obj = MyClass(2) >>> obj.x 正在获取属性x 2</pre>

我们使用__getattribute__魔法方法时,要返回父类的方法,不然很难写对,下面代码是一个陷阱,会产生无限递归。

<pre class="brush:php;toolbar:false">class MyClass:     def __init__(self, x):         self.x = x     def __getattribute__(self, item):         print('正在获取属性{}'.format(item))         return self.item          >>> obj = MyClass(2) >>> obj.x   File "xxx", line 11, in __getattribute__     print('正在获取属性{}'.format(item)) RecursionError: maximum recursion depth exceeded while calling a Python object</pre>

上面的代码看起来似乎是对的,但却调入了无限递归的陷阱,相当于

<pre class="brush:php;toolbar:false">def __getattribute__(self, item):     print('正在获取属性{}'.format(item))     return self.__getattribute__(item)</pre>

要十分警惕。

另外,内置的getattr和hasattr也会触发这个魔法方法。

<pre class="brush:php;toolbar:false">>>> getattr(obj, 'x', None) 正在获取属性x 2 >>> hasattr(obj, 'x', None) 正在获取属性x True</pre>

其他细节需要注意

<pre class="brush:php;toolbar:false">class MyClass:     x = 999          def __init__(self, x):         self.x = x     def __getattribute__(self, item):         print('正在获取属性{}'.format(item))         return super(MyClass, self).__getattribute__(item)</pre>

上面代码中,定义了一个类属性x和一个实例属性x,这两个属性同名,根据Python语法规则,当对象获取属性x的时候,首先会在实例属性中寻找,如果找不到才回去类属性中查找。

<pre class="brush:php;toolbar:false">>>> obj = MyClass(2) >>> print(obj.x) 正在获取属性x 2 >>> del obj.x  #删除了实例属性x >>> print(obj.x)  #此时访问的是类属性 正在获取属性 999</pre>

这样就能印证了上面所说__getattribute__的查找顺序。通常该方法在框架中可能会用到,一般情况下无需使用。

您可能感兴趣的文章:
Python魔法方法之__getattr__和getattribute
python魔法方法有什么用
Python如何利用动态属性处理JSON数据源
Python中处理属性的重要属性和函数是什么
天猫魔盘无法上网 天猫魔盘不能上网怎么办
java中getAttribute和getParameter的区别
光影魔术手给照片添加边框 光影魔术手照片边框添加教程
魔兽争霸3游戏卡如何设置 魔兽争霸3游戏卡设置方法
python魔法方法是什么
python描述符是什么意思

[关闭]
~ ~