[英]Why are there two magic methods to access object attributes in Python?
两种方法有不同的用途。
所有属性访问均调用__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)
在这里_wrapped
和foo
直接在Proxy()
上找到,但是如果您尝试访问bar
,则该属性在Proxy
类上不存在,而是调用__getattr__
,将其转换为对self._wrapped
属性访问。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.