Class 装饰器为其他 Class 方法预处理 kwargs

Class Decorator to Pre-Process kwargs for Other Class Methods

我的 CurrencyTools class 中有一套方法,我希望能够接受 kwarg 不同货币缩写的输入。例如,我希望每个方法都接受 'usd' 或 'eur' kwarg 参数。然而,为了进行计算,这些函数需要以美元为单位的输入,因此每个方法的第一行都是使用 self.convert_to_usd() 将非美元货币输入转换为美元。这个转换步骤似乎是重复的。我如何创建一个调用 class 方法 self.convert_to_usd 的装饰器来自动执行此转换“预处理”步骤并将转换后的美元金额传递给这些方法?我不确定装饰器如何到达 self 以调用 self.convert_to_usd 方法。

class CurrencyTools(object):
   def __init__(self, eurusd_exchange_rate):
      self.eurusd_exchange_rate = eurusd_exchange_rate

   def convert_to_dollars(): 
   #### ?? Decorator ?? ####

   @convert_to_dollars
   def do_calculation(self, **kwargs):
      # usd = self.convert_to_usd(**kwargs) if 'usd' not in kwargs.keys() else kwargs['usd']
      # decorator avoids repeating the line above at the start of every function
      # do calculation with usd

   def convert_to_usd(self, **kwargs):
      return kwargs['eur'] * self.eurusd_exchange_rate

# example use
CurrencyTools(eurusd_exchange_rate=1.1).do_calculation(eur=100)

装饰器可以用自己设计的另一个函数替换被装饰的方法。那个新的包装函数可以有一个 self 参数,并且 Python 使方法自动获取传递给它们的实例作为第一个参数的机制将像正常一样工作。只有当您将 self 传递给原始函数时,您才需要显式传递它。

我怀疑你想要这样的东西:

def autoconvert_decorator(method):
    def wrapper(self, *args, eur=None, usd=None, **kwargs): # self gets provided like normal
        if usd is None:
            usd = self.convert_to_usd(eur=eur)
        return method(self, *args, usd=usd, **kwargs) # we have to explicitly pass self here
    return wrapper

你可以稍微改变一下,继续从 kwargs 中找出 usd and/or eur 关键字参数,但我认为代码更清晰如果您在包装函数的签名中明确命名它们。