python 的魔方方法__getattribute__ 和__getattr__方法介绍

python 中有2个获取对象属性的方法__getattribute__ 和__getattr__方法比较容易混淆,

接下来说明下这2个魔方方法的区别及用法:

 

__getattr__方法

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

分析:首先我们定义了一个类并设置了一个实例属性x,重新定义__getattr__这个方法。在执行的时候,首先实例化obj这个对象,传递了一个1的实参,我们输出obj.x查看属性值,有找到并且为1;再次查找一个不存在的属性y,然后自动调用__getattr__这个方法,然后打印出没找到属性。(这里如果不重新定义__getattr__,会报AttributeError异常)。

class MyClass:

     def __init__(self, x):

           self.x = x

>>> obj = MyClass(1)

>>> obj.y

AttributeError: 'MyClass' object has no attribute 'y'

**调用__getattr__详细过程如下:**
obj.attr

  1. 首先会在对象的实例属性中寻找,找不到执行第二步
  2. 来到对象所在的类中查找类属性,如果还找不到执行第三步
  3. 来到对象的继承链上寻找,如果还找不到执行第四步
  4. 调用obj.__getattr__方法,如果用户没有定义或者还是找不到,抛出AttributeError异常,属性查找失败!

 

__getattribute__方法

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

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

 

**注意上面例子标红处,需要返回父类的方法,若是返回其他很容易产生无限递归

例:

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

 

调用此方法查找属性的过程与__getattr__方法一致。

====================================================================================

总的来说:

这2个方法作用都是相同的,都是查找对象的属性值,查询不到抛出异常。一般我们想自定义查找属性方法的时候,用__getattr__方法比较多,__getattribute__方法在调用对象属性的时候首先调用,而当__getattribute__查找失败,就会去调用__getattr__方法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值