覆盖方法而不是变量的__getattr__

时间:2016-06-24 11:54:22

标签: python

我想让下一个代码正常工作

class A(object):
    def __getattr__(self, item):
        print item
        return self.item
    def x(self):
        print 4
a = A()
a.x()

并且输出将是

x
4

我知道它不起作用因为x就像一个静态变量,而不是一个实例变量。 我看到了这个__getattr__ for static/class variables in python,它似乎不适用于我的情况 怎么办呢?

THX

1 个答案:

答案 0 :(得分:4)

您的代码存在一些明显的问题:

class A(object):

    def __getattr__(self, item):  # 1
        print item
        return self.item  # 2

    def x(self):  # 1 again
        print 4
    只有在无法以正常方式找到__getattr__时才会调用
  1. item。因此,对于item == 'x',它永远不会被调用。
  2. 可能也是如此,因为self.item查找属性item,而不是与分配给item的内容相对应的属性。这不存在,因此会调用__getattr__。如果您尝试A().y(),您将获得RuntimeError: maximum recursion depth exceeded while calling a Python object
  3. 相反,我认为你想使用__getattribute__,它总是被调用。但是,您需要注意不要获得相同的运行时错误;在这里我通过调用__getattribute__的超类实现来避免它,调用getattr(self, item)的天真方式会失败:

    class A(object):
    
        def __getattribute__(self, item):
            print item
            return super(A, self).__getattribute__(item)
    
        def x(self):
            print 4
    

    给出了:

    >>> A().x()
    x
    4
    >>> A().y()
    y
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 4, in __getattribute__
    AttributeError: 'A' object has no attribute 'y'
    

    请注意,__getattr____getattribute__同样适用于属性和方法(或多或少只是可调用属性)。