使用classmethod为每个实例注册唯一的回调

时间:2013-08-26 12:46:57

标签: 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')

1 个答案:

答案 0 :(得分: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