Python:对装饰器非常困惑

oro*_*aki 2 python decorator

我以为我理解装饰者但不再理解了.装饰器只在创建函数时起作用吗?

我想创建一系列函数,这些函数都有一个名为'ticket_params'的必需参数,这是一个字典.然后用类似的东西装饰它们@param_checker(['req_param_1', 'req_param_2'])然后如果'req_param_1'和'req_param_2'不在字典中,则引发一个自定义的Exception子类.我觉得这一切都错了吗?

在调用代码中会是这样的:

@param_checker(['req_param_1', 'req_param_2'])
def my_decorated_function(params):
    # do stuff

params = {'req_param_1': 'Some Value'}
my_decorated_function(params)

# exception would be raised here from decorator.
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 11

def声明后立即应用装饰器; 等价是:

@param_checker(['req_param_1', 'req_param_2'])
def my_decorated_function(params):
    # do stuff
Run Code Online (Sandbox Code Playgroud)

与以下内容完全相同:

def my_decorated_function(params):
    # do stuff
my_decorated_function = param_checker(['req_param_1', 'req_param_2'])(my_decorated_function)
Run Code Online (Sandbox Code Playgroud)

因此,工作param_checker是返回一个函数,该函数将要装饰的函数作为其参数,并返回另一个执行所需操作的函数.好的到目前为止?

编辑:所以,这是一个实现...:

import functools

def param_checker(reqs):
  reqs = set(reqs)
  def middling(f):
    @functools.wraps(f)
    def wrapper(params):
      missing = reqs.difference(params)
      if missing:
        raise TypeError('Missing parms: %s' % ', '.join(sorted(missing)))
      return f(params)
    return wrapper
  return middling
Run Code Online (Sandbox Code Playgroud)


And*_*Dog 5

装饰器只在函数上调用一次,也就是说,当def语句解析时如下:

@mydecorator
def myfunction(): ...
Run Code Online (Sandbox Code Playgroud)

我认为你的意思是这样的:

class param_checker:
  def __init__(self, l):
    self.l = l

  def __call__(self, functionToBeDecorated):
    def wrapper(*args, **kwargs):
      if any(necessary not in kwargs["ticket_params"] for necessary in self.l):
        raise MyCustomException
      return functionToBeDecorated(*args, **kwargs)

    return wrapper
Run Code Online (Sandbox Code Playgroud)

如果你不明白,请告诉我;)