如何在不破坏python经典类中的默认行为的情况下实现__getattr__方法

时间:2014-05-24 04:56:30

标签: python getattr

我想在python经典类中添加一些日志记录到__getattr__方法。它运行正常,但是当使用运算符重载时,出了点问题。

我的代码如下:

class A:
    def __getattr__(self, item):
        print('attr:'+ item)
    def __getattribute__(self, item):
        print('attribute:' + item)
        return object.__getattribute__(self, item)
    def __add__(self, other):
        return 2

b = A()
a = b + 1
print(a)

在第a = b + 1行中,它将运行__getattr__方法,item的值将为__coerce__。在这种情况下,我不知道如何处理它。

1 个答案:

答案 0 :(得分:3)

您遇到的问题是__getattr__方法正在返回None。由于这是一个有效的属性值,Python不知道这只是一个没有return语句的函数的默认返回值。

如果您无法从__getattr__返回任何内容,则默认情况下应该提出AttributeError而不是返回None。在这种特定情况下,Python正在检查__coerce__方法。如果有AttributeError,它将被抑制,解释器将依赖其他行为(使用__add__)。尝试这样的事情:

def __getattr__(self, item):
    print('attr:', item)
    raise AttributeError("%s object has no attribute named %r" %
                         (self.__class__.__name__, item))

现在,Python对__coerce__的自动查找将失败,但由于它以预期的方式失败,因此将忽略该异常并且将按预期调用__add__方法。

最后一件事:Python中的旧式类已彻底过时(并已从Python 3中删除)。你不应该使用它们,除非你需要保持在2.2之前的Python版本上运行的非常旧的软件的兼容性(这是在12年前的2001年发布的,因此这种兼容性问题变得有点荒谬)。对于不必使用这些古老Python版本的新代码,您应该在任何地方使用新式类。由于您使用的是旧式课程,因此永远不会调用__getattribute__方法(仅__getattr__)。