2013-04-10 37 views
2

尝试将类方法绑定到函数时出现错误。为什么?将类方法绑定到外部函数

def foo(): 
    print "Hello world" 

class something(object): 
    bar = foo 

test = something() 
test.bar() 

TypeError: foo() takes no arguments (1 given) 

而且,如果我无法修改foo,我可以做到这一点从改编类定义中?

回答

7

一个简单的方法来做到这一点是包裹功能在里面staticmethod答:

class A(): 
    bar = staticmethod(foo) 

>>> test = A() 
>>> test.bar() 
Hello world 
+0

我很喜欢这个解决方案。我想这只适用于如果我不需要访问该函数内的实例(但这是我更新中假设的一部分) – 2013-04-10 22:33:25

1

当您以这种方式调用类方法时,您会将类实例作为第一个参数传递。 当您致电test.bar实际上发生的更像是bar(test)。你传递一个参数给方法。

2

python中的类方法总是至少需要一个参数,通常称为self。这个例子是从official Python tutorial采取:

# Function defined outside the class 
def f1(self, x, y): 
    return min(x, x+y) 

class C: 
    f = f1 
    def g(self): 
     return 'hello world' 
    h = g 

注意,这两种方法,而不管它们是否是类的外部或内部定义,采取self作为一个参数。

编辑:如果你真的不能改变你的foo功能,那么你可以做这样的事情:

>>> def foo(): 
...  print "Hello World" 
... 
>>> class something(object): 
...  def bar(self): foo() 
... 
>>> test = something() 
>>> test.bar() 
Hello World 
+0

说我不能修改'foo'(或者说我宁愿不改变它的签名)。我可以在班级定义内做这种改编吗? – 2013-04-10 22:25:21

+1

我编辑了我的答案来回答你的问题。 – srgerg 2013-04-10 22:30:14

+1

太棒了。谢谢@srgerg。我爱Python。 – 2013-04-10 22:30:53

1

请记住,当蟒蛇类调用它的一个方法,它会在一传self的说法。你需要在你的代码,以说明:

​​

您可以阅读所有关于在Python Documentation

最简单的解决方法类不传递一个self,我能想到的是:

def foo(): 
    print ("Hello world") 

class something(object): 
    bar = [foo] # contains pointer to static method 

test = something() 
test.bar[0]() # calls the static method 
+0

谢谢。我已经更新了OP来澄清我正在寻找一种不需要修改'foo'的方法,而只需要修改类定义本身。 – 2013-04-10 22:26:52

+0

@ user815423426编辑,可能有更好的方法,但这个工程,我想你可以添加尽可能多的不同功能,你想现在。 – Serdalis 2013-04-10 22:35:41

1

类方法都有类的实例的第一个参数。所以添加一个参数到你的功能,它会工作。

1

初始def创建一个名为foo的函数对象。由于它不在任何类中,所以它只是一个不带任何参数的函数。赋值bar = foo只是将新名称test.bar赋予同一个函数对象。然而,调用test.bar()假定bar是类方法,并将对象test作为第一个参数传递给方法(通常称为self)。您可以将其作为与something.bar()的静态方法进行调用,而不会出现错误。