Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用classmethod为每个实例注册唯一回调_Python_Python 2.7_Decorator_Class Method - Fatal编程技术网

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