python的getattr和setattr,python中get_attribute
Python中有两个神奇的方法让人摸不着头脑:__getattr__和getattribute。我们通常定义__getattr__但从不定义getattribute。下面我们来看看两者的区别。
__getattr__魔法方法
classMyClass:
def__init__(self,x):
self.x=x
def__getattr__(self,item):
Print({}属性已找到!。格式(项目))
returnNone
obj=MyClass(1)
对象x
一个
对象y
找到y属性!
我们定义了一个MyClass类,并将实例属性设置为值为1的X。Obj是这个类的一个实例。get obj . x返回1,get obj . y却发现找不到属性。原因是obj的实例变量不含y,找不到属性时会调用__getattr__方法。
* *调用__getattr__的详细过程如下:* *
对象属性
1.首先,您将在对象的实例属性中查找它,如果找不到,请执行第二步。
2.到对象所在的类去找类属性,如果还是找不到,执行第三步。
3.转到对象的继承链并寻找它。如果还是找不到,执行第四步。
4.调用obj。__getattr__方法。如果用户没有定义或者还是找不到,抛出AttributeError异常,属性查找失败!
classMyClass:
def__init__(self,x):
self.x=x
obj=MyClass(1)
对象y
Error:“我的类”objecthasnoattribute“a”如上面的代码所示,如果__getattr__的魔方法没有定义,找不到属性,就会抛出异常。
相关:《Python视频教程》
__getattribute__魔法方法
当我们调用一个对象的属性时,我们首先调用__getattribute__ magic方法。
对象x
Obj。__getattribute__(x)正如上面的代码一样,这两个代码实际上是等价的。当__getattribute__查找失败时,将调用__getattr__方法。
代码演示
classMyClass:
def__init__(self,x):
self.x=x
def__getattribute__(self,item):
打印(获取属性{} )。格式(项目))
returnsuper(MyClass,self)。__getattribute__(项目)
obj=MyClass(2)
对象x
获取属性x
2
>我们使用__getattribute__魔法方法时,要返回父类的方法,不然很难写对,下面代码是一个陷阱,会产生递归。
classMyClass:上面的代码看起来似乎是对的,但却调入了递归的陷阱,相当于def__init__(self,x):
self.x=x
def__getattribute__(self,item):
print('正在获取属性{}'.format(item))
returnself.item
>>>obj=MyClass(2)
>>>obj.x
File"xxx",line11,in__getattribute__
print('正在获取属性{}'.format(item))
RecursionError:maximumrecursiondepthexceededwhilecallingaPythonobject
def__getattribute__(self,item):要十分警惕。print('正在获取属性{}'.format(item))
returnself.__getattribute__(item)
另外,内置的getattr和hasattr也会触发这个魔法方法。
>>>getattr(obj,'x',None)其他细节需要注意正在获取属性x
2
>>>hasattr(obj,'x',None)
正在获取属性x
True
classMyClass:上面代码中,定义了一个类属性x和一个实例属性x,这两个属性同名,根据Python语法规则,当对象获取属性x的时候,首先会在实例属性中寻找,如果找不到才回去类属性中查找。x=999
def__init__(self,x):
self.x=x
def__getattribute__(self,item):
print('正在获取属性{}'.format(item))
returnsuper(MyClass,self).__getattribute__(item)
>>>obj=MyClass(2)这样就能印证了上面所说__getattribute__的查找顺序。通常该方法在框架中可能会用到,一般情况下无需使用。>>>print(obj.x)
正在获取属性x
2
>>>delobj.x#删除了实例属性x
>>>print(obj.x)#此时访问的是类属性
正在获取属性
999
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。