我如何重写类的__getattr__方法而不破坏默认行为?
当前回答
重写__getattr__应该没问题——__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__将首先被调用(仅适用于新样式类,即继承自object的类)。在这种情况下,你可以像这样保留默认行为:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
请参阅Python文档了解更多信息。
其他回答
重写__getattr__应该没问题——__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__将首先被调用(仅适用于新样式类,即继承自object的类)。在这种情况下,你可以像这样保留默认行为:
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
请参阅Python文档了解更多信息。
class A(object):
def __init__(self):
self.a = 42
def __getattr__(self, attr):
if attr in ["b", "c"]:
return 42
raise AttributeError("%r object has no attribute %r" %
(self.__class__.__name__, attr))
>>> a = A()
>>> a.a
42
>>> a.b
42
>>> a.missing
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: 'A' object has no attribute 'missing'
>>> hasattr(a, "b")
True
>>> hasattr(a, "missing")
False
为了扩展Michael answer,如果你想使用__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'
推荐文章
- 我应该在.gitignore文件中添加Django迁移文件吗?
- 每n行有熊猫
- 实例属性attribute_name定义在__init__之外
- 如何获取在Python中捕获的异常的名称?
- 第一次出现的值大于现有值的Numpy
- 如何从Python函数中返回两个值?
- 前一个月的Python日期
- Python中方括号括起来的列表和圆括号括起来的列表有什么区别?
- Python日志记录不输出任何东西
- 每n秒运行特定代码
- SQLAlchemy是否有与Django的get_or_create等价的函数?
- 如何将python datetime转换为字符串,具有可读格式的日期?
- 美丽的汤和提取div及其内容的ID
- 在Python中重置生成器对象
- 用Python构建最小的插件架构