【问题标题】:How can I decorate a "callable" class with a class decorator?如何用类装饰器装饰“可调用”类?
【发布时间】:2013-07-30 08:34:42
【问题描述】:

我希望装饰一个“可调用”类(定义了__call__ 方法的类),以便我可以在调用__init__ 之前启动后台服务并在调用它本身之前操作传递的参数包括已启动的服务的详细信息。

所以,例如:

@init_service # starts service on port 5432
class Foo(object):
  def __init__(self, port=9876):
    # init here. 'port' should now be `5432` instead of the original `9876`

  def __call__(self):
    # calls the background service here, using port `5432`

func = Foo(port=9876)
...
result = func()

init_service 类将有一个带有端口号的类属性,以便以后可以关闭服务。

【问题讨论】:

  • 这与可调用的类无关。

标签: python decorator python-decorators callable


【解决方案1】:

您正在尝试修补__init__ 方法;有一个__call__ 方法的事实在这里没有任何可能性。

您通常会使用常规(函数)装饰器来装饰 __init__ 方法;如果您使用类装饰器,则使用一个子类化装饰类的装饰器:

def init_service(cls):
    class InitService(cls):
        def __init__(self, port='ignored'):
            super(InitService).__init__(5432)

    return InitService

【讨论】:

  • 有什么方法可以在init_service 函数之外定义类(由于服务初始化方法,它相当大),然后重新定义它从init_service 函数中继承的对象?
  • @unpluggd:您需要一个定义继承的动态类。这可以是一个包装类,它只执行class WrapperInitService(RealInitServiceClass, cls),其中WrapperInitService 在装饰器之外。这有一些注意事项(主要与必须使用 super() 来覆盖您覆盖的任何内容有关)但它应该可以正常工作。
猜你喜欢
  • 2014-01-14
  • 2020-01-11
  • 2019-11-16
  • 2019-02-03
相关资源
最近更新 更多