开发者

Implementing a callback in Python - passing a callable reference to the current function

I want to implement the Observable pattern in Python for a couple of workers, and came across this helpful snippet:

class Event(object):
    pass

class Observable(object):
    def __init__(self):
        self.callbacks = []
    def subscribe(self, callback):
        self.callbacks.append(callbac开发者_Python百科k)
    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)

Source: Here

As i understand it, in order to subscribe, I would need to pass a callback to the function that is going to be called on fire. If the calling function was a class method, presumably I could have used self, but in the absence of this - how could I directly get a callback that can be useful for the self.callbacks.append(callback) bit?


Any defined function can be passed by simply using its name, without adding the () on the end that you would use to invoke it:

def my_callback_func(event):
    # do stuff

o = Observable()
o.subscribe(my_callback_func)

Other example usages:

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>>)


To add to Amber's main answer above, this is a complete example of how two classes can be used to implement a callback from one to another.

I dummied this up to satisfy my own curiosity on whether it would work or not - particularly given that register only seems to be called with a function being passed, but now that I've seen this example work, the function must be passed with a context of the object to which it is attached.

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 !!
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜