为什么没有为缺少“神奇”调用的方法调用__getattr__?

时间:2012-09-07 03:32:12

标签: python python-3.x getattr

我正在尝试实现一个类,其中尝试访问当前类或其任何祖先中不存在的任何属性将尝试从成员访问这些属性。以下是我想要做的一个简单的版本。

class Foo:
    def __init__(self, value):
        self._value = value

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

if __name__ == '__main__':
    print(Foo(5) > Foo(4)) # should do 5 > 4 (or (5).__gt__(4))

但是,这会引发TypeError。即使使用operator模块的attrgetter类也可以做同样的事情。我正在看the documentation regarding customizing attribute access,但我觉得它不容易阅读。我怎么能绕过这个?

2 个答案:

答案 0 :(得分:7)

如果我理解正确,你所做的是正确的,但它仍然无法用于你正在尝试使用它。原因是隐式魔术方法查找不使用__getattr__(或__getattribute__或任何其他此类事物)。这些方法实际上必须使用它们的魔术名称。您的方法适用于普通属性,但不适用于魔术方法。 (请注意,如果您明确地执行Foo(5).__lt__(4),它将起作用;它只是隐式的“魔术”查找 - 例如,在使用__lt__时调用< - 这是阻止。)

This post描述了一种使用元类自动生成魔术方法的方法。如果您只需要某些方法,您可以手动在类上定义它们。

答案 1 :(得分:1)

__*__方法除非实际存在,否则无效 - 因此__getattr____getattribute__都不允许您代理这些调用。您必须手动创建每个方法。

是的,这确实涉及相当多的复制和粘贴。是的,在这种情况下它完全没问题。

您可以使用werkzeug LocalProxy类作为基础或代替您自己的类;使用LocalProxy时,您的代码将如下所示:

print(LocalProxy(lambda: 5) > LocalProxy(lambda: 4))