编写一个接受Python回调的类?

Cha*_*ich 8 python callback

我需要编写一个类,允许子类使用函数名称设置属性.然后,该函数必须可以从类的实例中调用.

例如,我说我需要编写一个Fruit类,子类可以在欢迎消息中传递.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: ")
Run Code Online (Sandbox Code Playgroud)

我需要公开一个可以被这段代码使用的API(要清楚,这段代码不能改变,说它是第三方代码):

def apple_print(f):
    print "%sI am an Apple!" % f

class Apple(Fruit):
    print_callback = apple_print
Run Code Online (Sandbox Code Playgroud)

如果我跑:

mac = Apple()
Run Code Online (Sandbox Code Playgroud)

我想得到:

来自Fruit的消息:我是Apple!

相反,我得到:

TypeError:apple_print()只取1个参数(给定2个)

我认为这是因为self作为第一个参数传入.

那么我该如何编写Fruit类呢?谢谢!

Joh*_*kin 8

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: ")
Run Code Online (Sandbox Code Playgroud)

  • 顺便说一句,同样值得注意的是,在 Python 3.x 中,方法的 `im_func` 属性被重命名为 `__func__`。 (2认同)

小智 5

您可以直接使用:

class Apple(Fruit):
    print_callback = staticmethod(apple_print)
Run Code Online (Sandbox Code Playgroud)

或者:

class Apple(Fruit):
    print_callback = classmethod(apple_print)
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,您只会得到一个参数(原始参数)。在第二个中,您将收到两个参数,其中第一个是调用它的类。

希望这会有所帮助,并且更短且更简单。