2012-03-27 51 views
1

在我的头上缠绕一点点麻烦。我相信答案很简单,但它一直在推动着我。TypeError:B2()只需要1个参数(给出0)...为什么这个函数被完全调用为named或变量

在下面的代码:

class f1(): 
    valnum=1 

    def A1(self): 
     self.valnum=5 
     print self.valnum 

    def B2(self): 
     self.valnum=10 
     print self.valnum 


    funlist=[A1,B2] 


x=f1 
x() 

x().A1() 
x().funlist[1]() 

A1()会如预期执行,但不B2()。最终,我想让代码从列表中调用一个随机函数,但TypeError: B2() takes exactly 1 argument (0 given)一直在阻碍我。为什么这是最好的解决方案。

谢谢。

回答

3

x().funlist[1]()没有按照你的想法去做。

funlist是一个类属性。它包含对实例方法A1B1的引用,但实际上并未将它们与任何实例相关联 - 它们被称为未绑定的方法。

当你调用该代码时,你可能试图说“在0123k上调用实例x中的第一个函数”。但它实际上做的是“调用与类x类相关的类属性funlist中引用的函数”,这根本不是一回事。

现在,Python实际上并没有在绑定方法和非绑定方法之间做出很大区别。您可以假冒通过传递实例作为第一个参数绑定 - 所以这会工作:

x_instance = x() 
x_instance.funlist[1](x_instance) 
+1

事实上,'funlist'包含*功能*,而不是实例方法或结合的方法。在从类对象中检索函数之前,函数不会成为未绑定的方法,并且在创建funlist时类对象还不存在。 – 2012-03-27 10:52:15

+0

谢谢,这是一个有用的说明。 – 2012-03-27 11:02:37

+0

或者,将funlist的定义移动到'__init__'中并让它获取实例方法并成为一个实例属性。 – agf 2012-03-27 11:09:30

0
x().funlist[1] 

评估的方法B2,但不bind它的临时对象x()x().B2会做:

>>> f1().B2 
<bound method f1.B2 of <__main__.f1 instance at 0x1cb4d40>> 
>>> f1().funlist[1] 
<function B2 at 0x1c3cb90> 

的解决方案是明确地传递了“self”对象的方法:

obj = f1() 
obj.funlist[1](obj)