繁体   English   中英

为什么有两种魔术方法可以访问Python中的对象属性?

[英]Why are there two magic methods to access object attributes in Python?

我正在研究Python的对象属性访问模式( 描述符方法指南数据模型docs )。 我不清楚的是Guido为什么同时为对象提供__getattr____getattribute__方法? 它们都做完全相同的事情,但是调用方式不同。

对我来说,这似乎可以通过更差的设计来修复设计不好的类。 我的意思是,如果某些东西需要重构,则不应以高优先级或更高优先级调用魔术方法将其“粘合”。

问题是-如果一种方法足够完美,为什么会有两种类似的方法?

我不是指描述符,这是有所不同的。

两种方法有不同的用途。

所有属性访问均调用__getattribute__ __getattr____getattribute__找不到属性时才被调用。

实现正确的__getattr__方法要比实现__getattribute__替换容易得多。 当然,在那种情况下,您可以不用__getattr__来做,但这也将使实现通用用例变得更加困难。

例如,在__getattr__您可以轻松地访问self上的其他现有属性; 如果您需要self.bar来实现动态属性,那么这样做很容易。 __getattribute__您无法通过常规属性访问self上的任何内容,因为所有这些都由__getattribute__方法处理; 如果尝试,最终将导致无限递归。 相反,该方法内的所有属性访问都必须使用super(ClassName, self).__getattribute__(name)调用。

注意__getattribute__ 总是被实现; object.__getattribute__提供默认的实现。 仅在需要拦截默认行为时才使用__getattribute__ 说您需要在特殊情况下覆盖现有属性,或覆盖常规描述符行为 有关覆盖现有属性访问的示例,请参见了解__getattribute__

使用__getattr__进行其他操作; 例如动态属性,这些属性在对象上尚不存在。 假设您要提供一个代理类,其中大多数属性访问都传递给包装的对象:

class Proxy(object):
    def __init__(self, wrapped):
        self._wrapped = wrapped

    def foo(self):
        return self._wrapped.foo() + 42

    def __getattr__(self, name):
        return getattr(self._wrapped, name)

在这里_wrappedfoo直接在Proxy()上找到,但是如果您尝试访问bar ,则该属性在Proxy类上不存在,而是调用__getattr__ ,将其转换为对self._wrapped属性访问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM