我想在设计库时更容易使用装饰器注册回调,但问题是它们都使用了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')
答案 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