1

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

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

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

1 回答 1

1

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

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

?

于 2013-08-26T12:53:09.260 回答