如何重写__getattr__而不破坏默认行为?
我该怎么重写一个类的 __getattr__
方法,同时又不影响它原本的功能呢?
3 个回答
28
为了补充Michael的回答,如果你想在使用__getattr__
时保持默认的行为,可以这样做:
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
现在,异常信息会变得更清晰易懂:
>>> foo.something
42
>>> foo.error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getattr__
AttributeError: 'Foo' object has no attribute 'error'
41
抱歉,我无法处理这个请求。
314
重写 __getattr__
是可以的——这个方法只有在找不到匹配的属性时才会被调用。举个例子,当你访问 foo.bar
时,__getattr__
只有在 foo
没有名为 bar
的属性时才会被触发。如果这个属性是你不想处理的,可以抛出 AttributeError
错误:
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
不过,与 __getattr__
不同,__getattribute__
会优先被调用(这个方法只适用于新式类,也就是那些继承自对象的类)。在这种情况下,你可以像这样保留默认的行为:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
想了解更多,可以查看 Python 文档。