getattr出错
我本来想去看一个关于如何在Python中通过字符串调用模块函数的问题,但每当我在程序中调用我的类时,就会出现这个错误:TypeError: unbound method bar() must be called with foo instance as first argument (got nothing instead)。
有人能帮我解决这个问题吗?
2 个回答
1
我们来看这个例子:
class Foo:
def bar(self):
print 'bar'
@classmethod
def baz(cls):
print 'baz'
@staticmethod
def qux():
print 'qux'
def quux():
print 'quux'
Foo.quux = quux # note: Foo.quux is a function attribute NOT a method
然后你可以根据调用这些方法的方式,得到不同的成功标准:
f = Foo()
f.bar() # works
getattr(f, 'bar')() # works
getattr(Foo, 'bar')() # TypeError
getattr(Foo, 'bar')(f) # works
f.baz() # works
getattr(f, 'baz')() # works
getattr(Foo, 'baz')() # works
等等。这里的基本概念是,当你调用一个方法时,使用的语法是 obj.method(...)
,这个对象本身会作为第一个 self
参数传递;但是当你把同样的方法当作类的一个属性来使用时,这个特殊的替换就不会发生。这一点在 getattr
函数中也是适用的。
9
这里有一个典型的情况,会导致你所描述的问题。
class Foo(object):
def bar(self,x):
print(x)
foo=Foo()
调用 getattr(Foo, 'bar')
会返回未绑定的方法 Foo.bar
。
getattr(Foo,'bar')(1)
结果是
类型错误:未绑定的方法 bar() 必须以 Foo 实例作为第一个参数调用(而不是 int 实例)
这个方法 Foo.bar
被称为“未绑定”,因为在调用时没有提供实例(比如 foo
)作为第一个参数。毕竟,如果只提供了类 Foo
,怎么能有实例呢?
另一方面,如果你提供了这个类的实例:
getattr(foo,'bar')(1)
结果是
1
因为 foo.bar
是一个“绑定”的方法——当调用 foo.bar
时,foo
会作为第一个参数提供。
附注:你的错误信息中提到,“...用 foo 实例调用...”。与我上面提到的错误信息相比,看来你的类名是小写的 foo
。请注意,PEP8 风格指南 建议类名总是用大写字母,而实例名用小写字母。这样做可以帮助你避免这个错误。