最新公告
  • 欢迎您光临网站无忧模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Python魔法方法之__getattr__和getattribute

    正文概述    2020-07-15   263

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

    Python魔法方法之__getattr__和getattribute

    __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

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

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

    obj.attr

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

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

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

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

    class MyClass:
        def __init__(self, x):
            self.x = x
    >>> obj = MyClass(1)
    >>> obj.y
    AttributeError: 'MyClass' object has no attribute 'a'

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

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

    __getattribute__魔法方法

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

    obj.x
    obj.__getattribute__(x)

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

    代码演示

    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

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

    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

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

    def __getattribute__(self, item):
        print('正在获取属性{}'.format(item))
        return self.__getattribute__(item)

    要十分警惕。

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

    >>> getattr(obj, 'x', None)
    正在获取属性x
    2
    >>> hasattr(obj, 'x', None)
    正在获取属性x
    True

    其他细节需要注意

    class MyClass:
        x = 999
        
        def __init__(self, x):
            self.x = x
        def __getattribute__(self, item):
            print('正在获取属性{}'.format(item))
            return super(MyClass, self).__getattribute__(item)

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

    >>> obj = MyClass(2)
    >>> print(obj.x)
    正在获取属性x
    2
    >>> del obj.x  #删除了实例属性x
    >>> print(obj.x)  #此时访问的是类属性
    正在获取属性
    999

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


    下载网 » Python魔法方法之__getattr__和getattribute

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元