将类方法绑定到外部函数

5

当我尝试将一个类方法绑定到一个函数时,会出现错误。为什么?

def foo():
    print "Hello world"

class something(object):
    bar = foo

test = something()
test.bar()

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

如果我无法修改foo,那么我能否在类定义内进行适配?

6个回答

11
在A内部将该函数用staticmethod包装是一种简单的方法:
class A():
    bar = staticmethod(foo)

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

我非常喜欢这个解决方案。我猜这只有在我不需要从函数内部访问实例时才能工作(但这是我更新中的假设的一部分)。 - Amelio Vazquez-Reina

5

在Python中,类方法总是需要至少一个参数,通常称为self。以下示例摘自官方Python教程

# 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

说我不能修改 foo(或者我更喜欢不改变它的签名)。我能在类定义内部进行这种适应吗? - Amelio Vazquez-Reina
1
太棒了。谢谢@srgerg。我喜欢Python。 - Amelio Vazquez-Reina
查看 @BrenBarn 的有趣解决方案,解决“无法更改 foo”问题。 - Amelio Vazquez-Reina
是的,我喜欢BrenBarn的解决方案更好。 - srgerg

1

记住,当Python类调用其方法时,它会传递一个self参数。你需要在你的代码中考虑到这一点:

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

class something(object):
    bar = foo

test = something()
test.bar()

你可以在Python文档中阅读有关类的所有内容。
我能想到的最简单的解决方法是不传递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

谢谢。我已经更新了原始帖子以澄清,我正在寻找一种不需要修改 foo,而只需要修改类定义本身的方法来实现这个目标。 - Amelio Vazquez-Reina
@user815423426 编辑,可能有更好的方法,但这个方法有效,我想现在你可以添加任意多个不同的函数了。 - Serdalis

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

1

类方法都有一个第一个参数,是该类的实例。因此,将参数添加到您的函数中,它就会起作用。


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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接