在Python中编写接受回调的类?
我需要写一个类,让它的子类可以设置一个属性,这个属性的名字是一个函数名。这个函数必须能从这个类的实例中调用。
举个例子,我想写一个水果类(Fruit),子类可以传入一个欢迎信息。这个水果类必须有一个可以设置的属性,叫做 print_callback。
class Fruit(object):
print_callback = None
def __init__(self, *args, **kwargs):
super(Fruit, self).__init__(*args, **kwargs)
self.print_callback("Message from Fruit: ")
我需要提供一个接口,让下面这段代码可以使用(为了说明,这段代码不能改动,假设它是第三方代码):
def apple_print(f):
print "%sI am an Apple!" % f
class Apple(Fruit):
print_callback = apple_print
如果我运行:
mac = Apple()
我希望得到:
来自水果的信息:我是一颗苹果!
但我得到的是:
类型错误:apple_print() 需要 1 个参数(给了 2 个)
我觉得这是因为 self 被当作第一个参数传进去了。
那么我该怎么写这个水果类呢?谢谢!
6 个回答
3
更新:根据abourget的建议,使用了staticmethod
:
试试这个:
def __init__(self, *args, **kwargs):
super(Fruit, self).__init__(*args, **kwargs)
# Wrap function back into a proper static method
self.print_callback = staticmethod(self.print_callback)
# And now you can do:
self.print_callback("Message from Fruit: ")
6
你可以直接使用:
class Apple(Fruit):
print_callback = staticmethod(apple_print)
或者:
class Apple(Fruit):
print_callback = classmethod(apple_print)
在第一种情况下,你只会得到一个参数(原始参数)。在第二种情况下,你会收到两个参数,第一个参数是你调用这个方法的类。
希望这对你有帮助,而且更简短、更简单。
11
在Python中,任何在类里面定义的函数都会被认为是方法。如果你想把它们当作普通的函数来使用,就需要去找它们的一些属性,来获取原始的函数对象:
def __init__(self, *args, **kwargs):
super(Fruit, self).__init__(*args, **kwargs)
# The attribute name was changed in Python 3; pick whichever line matches
# your Python version.
callback = self.print_callback.im_func # Python 2
callback = self.print_callback.__func__ # Python 3
callback("Message from Fruit: ")