如何在Python 3.1中的函数中使用__getattr__?

时间:2011-12-02 09:01:27

标签: python-3.x

我正在尝试在函数中重新定义 __ getattr __ 方法。

我试过这段代码:

def foo():
    print("foo")

def addMethod(obj, func):
    setattr(obj, func.__name__, types.MethodType(func, obj))

def __getattr__(obj, name):
    print(name)

addMethod(foo, __getattr__)

foo.bar

但是我收到了这个错误:

Traceback (most recent call last):
  File blah blah, line 14, in <module>
    foo.bar
AttributeError: 'function' object has no attribute 'bar'

我已经检查了“foo”函数,它确实有方法限制它,但似乎如果你动态设置它, __ getattr __ 赢了不会被叫。 如果我对一个类做同样的事情,如果我使用我的“addMethod”函数设置 __ getattr __ ,实例将不会调用 __ < em> getattr __ ,所以问题必须是动态调用!

但是如果我把 __ getattr __ 放在类的定义中,它显然会起作用。

问题是,如何将 __ getattr __ 添加到函数中以使其工作?我不能从头开始,因为它是一个功能!,我不知道该怎么做

谢谢!

2 个答案:

答案 0 :(得分:2)

嗯,你没有。如果您想要属性,请创建一个类。如果您希望实例可以调用,请为其定义__call__

class foo:
    def __call__(self):
        print("foo")

    def __getattr__(self, name):
        print(name)

f = foo()
f()   # foo
f.bar # bar

答案 1 :(得分:1)

你的问题是Python只会在对象的上查找__xxx__魔术方法,而不是对象本身。因此,即使您在__getattr__的实例上设置foo,也不会自动调用它。

这也是您使用class foo时遇到的问题:

class foo():
    pass

def addMethod(obj, func):
    setattr(obj, func.__name__, func)

def __getattr__(obj, name):
    print(name)

addMethod(foo, __getattr__)

foo.bar

这里Python在对象foo上查找bar,这意味着。 。

您添加到__getattr__的{​​{1}}方法被调用,而Python正在查看foo的元类,即{{1} }。

如果您将最后一行更改为

foo

并获取foo类的实例,它将起作用。