python的getattr和setattr,python中get_attribute

  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=999

  

  def__init__(self,x):

  self.x=x

  def__getattribute__(self,item):

  print('正在获取属性{}'.format(item))

  returnsuper(MyClass,self).__getattribute__(item)

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

  

>>>obj=MyClass(2)

  >>>print(obj.x)

  正在获取属性x

  2

  >>>delobj.x#删除了实例属性x

  >>>print(obj.x)#此时访问的是类属性

  正在获取属性

  999

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

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: