【问题标题】:Implementing a callback in Python - passing a callable reference to the current function在 Python 中实现回调 - 将可调用引用传递给当前函数
【发布时间】:2011-06-09 01:35:26
【问题描述】:

我想在 Python 中为几个工人实现 Observable 模式,并遇到了这个有用的 sn-p:

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)

来源:Here

据我了解,为了subscribe,我需要将回调传递给将在fire 上调用的函数。如果调用函数是class 方法,大概我可以使用self,但如果没有这个 - 我怎么能直接获得对self.callbacks.append(callback) 位有用的回调?

【问题讨论】:

    标签: python design-patterns functional-programming callback observer-pattern


    【解决方案1】:

    任何已定义的函数都可以通过简单地使用其名称来传递,而无需在用于调用它的末尾添加()

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

    【讨论】:

    • 方法中缺少 self 参数。
    • 哎呀。在实例方法上忘记了。静态方法没有得到self
    • 太好了,非常感谢 - 实际上我正在努力解决静态问题:)
    • @Amber,你将如何从 Observable 方法调用回调?假设 Observable 将方法存储在“回调”变量中 - 调用的语法是什么?
    【解决方案2】:

    为了补充上面 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 !!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多