Python 使用classmethod为每个实例注册唯一回调
我想在设计库时更容易使用装饰器注册回调,但问题是它们都使用相同的使用者实例 我试图让这两个例子共存于同一个项目中Python 使用classmethod为每个实例注册唯一回调,python,python-2.7,decorator,class-method,Python,Python 2.7,Decorator,Class Method,我想在设计库时更容易使用装饰器注册回调,但问题是它们都使用相同的使用者实例 我试图让这两个例子共存于同一个项目中 class SimpleConsumer(Consumer): @Consumer.register_callback def callback(self, body) print body class AdvancedConsumer(Consumer): @Consumer.register_callback def c
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的回调实现,正如上次定义的那样
decorator类的实现非常简单
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
如果你想修饰一个方法,你只能在其中得到一个函数,这样你就不能访问关于这个方法所包含的类的任何信息
但是如果每个类只有一个回调,为什么不调用它呢
class SimpleConsumer(Consumer):
def _callback(self, body):
print body
或者像这样做:
class SimpleConsumer(Consumer):
def my_func(self, body):
print body
_callback = my_func
?您可以使用类装饰器来完成:
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
如果你想修饰一个方法,你只能在其中得到一个函数,这样你就不能访问关于这个方法所包含的类的任何信息
但是如果每个类只有一个回调,为什么不调用它呢
class SimpleConsumer(Consumer):
def _callback(self, body):
print body
或者像这样做:
class SimpleConsumer(Consumer):
def my_func(self, body):
print body
_callback = my_func
?我甚至没有想到,但是获取
名称错误:名称“SimpleConsumer”未定义。
啊,对不起,我的错误,我会马上修复:)不用担心。这是一个如此愚蠢的问题,我在设计它时没有考虑到这一点,所以我很高兴在正确的方向上哪怕是最微小的推动=汉克斯,这确实有效。我在后台处理其他一些事情,比如是否以及如何确认消息已被处理,但是我会看看我是否能想出一个好的解决方案。如果你需要一个对消费者类的引用,那么你总是可以将register\u callback
作为消费者类的classmethod,并用@Consumer.register\u callback('my\u func')
调用它,我甚至没有想到,但是获取名称错误:没有定义名称“SimpleConsumer”。啊,对不起,我的错误,我会马上修复:)不用担心。这是一个如此愚蠢的问题,我在设计它时没有考虑到这一点,所以我很高兴在正确的方向上哪怕是最微小的推动=汉克斯,这确实有效。我在后台处理其他一些事情,比如是否以及如何确认消息已被处理,但是我会看看我是否能想出一个好的解决方案。如果你需要一个对消费者类的引用,那么你总是可以将register\u回调
作为消费者类的classmethod,并用@Consumer.register\u回调('my\u func')
调用它,如果只有一个回调函数,为什么不在子类中调用它\u callback
,并且永远不要弄乱注册?还需要做些什么吗?上面的例子中没有提到装饰器中的其他步骤,我希望继承Consumer类的类尽可能简单。最好我只希望回调和设置在那里处理(例如主机名、用户名、pw)。对我来说,装饰师是实现这一点的最干净的方法。如果还有其他步骤,那么这可能取决于他们这里最好的方法是什么。对我来说,最简单的解决方案就是总是调用回调函数\u callback
。如果只有一个回调函数,为什么不在子类中调用它\u callback
,并且永远不要弄乱注册?还需要做些什么吗?上面的例子中没有提到装饰器中的其他步骤,我希望继承Consumer类的类尽可能简单。最好我只希望回调和设置在那里处理(例如主机名、用户名、pw)。对我来说,装饰师是实现这一点的最干净的方法。如果还有其他步骤,那么这可能取决于他们这里最好的方法是什么。对我来说,最简单的解决方案就是总是调用回调\u callback
。