Python Decorator 3.0和装饰器的参数

YGA*_*YGA 6 python decorator

我很高兴看到最新版本的decoratorpython模块(3.0).与以前的迭代相比,它看起来更清晰(例如语法比以前更加含糖).

然而,对于那些自己提出论点的装饰者来说,它似乎有糟糕的支持(例如"酸"语法,可怕地延伸隐喻).有没有人有一个很好的例子说明你如何使用decorator3.0 干净利落地做到这一点?

 def substitute_args(fun, arg_sub_dict):
      def wrapper(arg):
         new_arg = arg_sub_dict.get(arg, arg)
         return fun(new_arg)

      # some magic happens here to make sure that type signature, 
      # __name__, __doc__, etc. of wrapper matches fun

 return wrapper
Run Code Online (Sandbox Code Playgroud)

小智 8

在这种情况下,您需要使您的函数返回装饰器.(任何事情都可以通过另一层次的间接解决......)

from decorator import decorator
def substitute_args(arg_sub_dict):
  @decorator
  def wrapper(fun, arg):
    new_arg = arg_sub_dict.get(arg, arg)
    return fun(new_arg)
  return wrapper
Run Code Online (Sandbox Code Playgroud)

这意味着substitute_args它不是一个装饰者本身,它是一个装饰工厂.这是没有decorator模块的等价物.

def substitute_args(arg_sub_dict):
  def my_decorator(fun):
    def wrapper(arg):
      new_arg = arg_sub_dict.get(arg, arg)
      return fun(new_arg)
    # magic to update __name__, etc.
    return wrapper
  return my_decorator
Run Code Online (Sandbox Code Playgroud)

三层深度不是很方便,但记住其中两个是定义函数的时候:

@substitute_args({}) # this function is called and return value is the decorator
def f(x):
  return x
# that (anonymous) decorator is applied to f
Run Code Online (Sandbox Code Playgroud)

这相当于:

def f(x):
  return x
f = substitude_args({})(f) # notice the double call
Run Code Online (Sandbox Code Playgroud)