在Python中实现回调 - 将可调用引用传递给当前函数

35 投票
2 回答
74635 浏览
提问于 2025-04-16 09:57

我想在Python中实现一个叫做Observable的模式,用于几个工作者,找到了一个很有用的代码片段:

class Event(object):
    pass

class Observable(object):
    def __init__(self):
        self.callbacks = []
    def subscribe(self, callback):
        self.callbacks.append(callback)
    def fire(self, **attrs):
        e = Event()
        e.source = self
        for k, v in attrs.iteritems():
            setattr(e, k, v)
        for fn in self.callbacks:
            fn(e)

来源:这里

我理解的是,要进行subscribe(订阅),我需要把一个回调函数传给一个在fire时会被调用的函数。如果这个调用的函数是一个class(类)的方法,我可以用self,但如果没有这个,那我该怎么直接获取一个对self.callbacks.append(callback)有用的回调呢?

2 个回答

0

为了补充Amber上面提到的主要回答,这里有一个完整的例子,展示了两个类是如何相互调用的。

我做这个例子是为了满足我自己的好奇心,想看看这样做是否可行——特别是因为register似乎只是在传递一个函数时被调用,但现在我看到这个例子能正常工作,说明这个函数必须和它所附加的对象的上下文一起传递。

class A():
    def register(self,fn):
        self.cb=fn
    
    def gimme(self,val):
        self.cb(val)

class B():
    def __init__(self, o):
        self.o = o
        self.o.register(self.callback)
    
    def callback(self,val):
        print(f"Got called with {val} !!")

    def go(self):
        self.o.gimme('test')

>>> a = A()
>>> b = B(a)
>>> b.go()
Got called with test !!
61

任何定义好的函数都可以通过直接使用它的名字来传递,不需要在后面加上(),因为加上这个符号是用来调用函数的:

def my_callback_func(event):
    # do stuff

o = Observable()
o.subscribe(my_callback_func)

其他用法示例:

class CallbackHandler(object):
    @staticmethod
    def static_handler(event):
        # do stuff

    def instance_handler(self, event):
        # do stuff

o = Observable()

# static methods are referenced as <class>.<method>
o.subscribe(CallbackHandler.static_handler)

c = CallbackHandler()
# instance methods are <class instance>.<method>
o.subscribe(c.instance_handler)

# You can even pass lambda functions
o.subscribe(lambda event: <<something involving event>>)

撰写回答