python - 使用类方法为每个实例注册唯一的回调

标签 python python-2.7 decorator class-method

我希望在设计库时更容易使用装饰器注册回调,但问题是它们都使用相同的 Consumer 实例。

我试图让这两个示例在同一个项目中共存。

class SimpleConsumer(Consumer):
     @Consumer.register_callback
     def callback(self, body)
         print body

class AdvancedConsumer(Consumer):
     @Consumer.register_callback
     def callback(self, body)
         print body

a = AdvancedConsumer()
s = SimpleConsumer()

这里发生的情况是,AdvancedConsumer 的回调实现将覆盖 SimpleConsumer 的回调实现,因为它是最后定义的。

装饰器类的实现非常简单。

class Consumer(object):
      def start_consumer(self):
            self.consuming_messages(callback=self._callback)

       @classmethod
       def register_callback(cls, function):        
           def callback_function(cls, body):
               function(cls, body)

           cls._callback = callback_function
           return callback_function

我对实现感到非常满意,但由于有人可能会注册第二个回调,我想确保这在将来不会成为问题。那么,有人对如何以非静态的方式实现这一点有建议吗?

此处显示的实现显然已简化,作为预防措施,我在代码中添加了类似的内容。

if cls._callback:
    raise RuntimeError('_callback method already defined')

最佳答案

您可以使用类装饰器来做到这一点:

def register_callback(name):
    def decorator(cls):
        cls._callback = getattr(cls, name)
        return cls
    return decorator

@register_callback('my_func')
class SimpleConsumer(Consumer):
     def my_func(self, body):
         print body

如果你想装饰一个方法,你只会得到其中的一个函数,因此你无法访问有关该方法所在类的任何信息。

但是,如果每个类只有一个回调可用,为什么不将其称为 _callback

class SimpleConsumer(Consumer):
     def _callback(self, body):
         print body

或者做类似的事情:

class SimpleConsumer(Consumer):
     def my_func(self, body):
         print body

     _callback = my_func

关于python - 使用类方法为每个实例注册唯一的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18444494/

相关文章:

python - 在 Python 中使用 '@patch.object' 和 'with patch.object' 有什么区别?

python - 在 Django 表单中将所有 CharField 表单字段输入转换为小写

python - 无法在 for 循环中同时按升序和降序范围打印

python - 为什么Behavior 记录的与 Django 的手动集成不起作用?

python - Django 基于类的 View - 意外的装饰器行为

python - 在装饰器包装器函数中访问装饰器参数

python - 将参数传播给结合其他装饰器的装饰器

python - 在 django rest 框架中过滤日期时间范围

python - 将 static 一些静态文件位置从/static/file.js 更改为/file.js

python - 带有可选字段的 WTForms FieldList