代码之家  ›  专栏  ›  技术社区  ›  sokeefe

初始化类中的Decorator变量

  •  2
  • sokeefe  · 技术社区  · 7 年前

    我正在使用一个可以接受变量的类中的装饰器,我想在类中初始化该变量。

    下面是我目前正在使用的示例(当前正在使用)。

    _RETRIES = 3
    
    class MyClass(object):
      def __init__(self, foo):
        self._foo=foo
    
      @retry.FuzzedIntervalsOnException(num_retries=_RETRIES)
      def my_method(self):
        return some_data
    

    然而,我想将此更改为接受以下内容 def __init__(self, foo, retries=3) 允许客户端决定重试次数。然而,实现这一点会引发一个未定义的变量错误。

    我希望得到下面这样的答案,但正确的答案似乎比这更复杂:

    class MyClass(object):
      def __init__(self, foo, retries=3):
        self._foo=foo
        self.retries=retries
    
      @retry.FuzzedIntervalsOnException(num_retries=self.retries)
      def my_method(self):
        return some_data
    

    是否有一种理想的方法来初始化要在装饰器中使用的类变量?

    非常感谢

    编辑: 有关重试的其他信息,以下是初始化。

    class FuzzedIntervalsOnException(object):
       """Retry on exception 
    
       args:
         delay: Time delay in seconds for each retry.
         num_retries: Total number of retries.
       """
       def __init__(self, delay, num_retries):
         ...
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Brett Beatty    7 年前

    您当前的 retry 可能看起来像这样:

    def retry(num_retries=0):
        def decorator(fn):
            def wrapper(*args, **kwargs):
                # ...
            return wrapper
        return decorator
    

    你想得到 self.retries ,但您不会引用 self 直到 wrapper 被调用。所以唯一的办法就是 自己重试次数 的内部 包装器 . 由于您没有向装饰器传递任何参数,因此也可以去掉一个层并执行以下操作:

    def retry(fn):
        def wrapper(self, *args, **kwargs):
            num_retries = self.retries
            # ...
        return wrapper