在Python中实现回调 - 将可调用引用传递给当前函数
我想在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>>)