我们如何将 *args 和 **kwargs 与装饰器一起使用

How do we use *args and **kwargs with decorators

我不明白为什么我们要这样做 args[0]["valid"] 而不是 args["valid"]

 user1 = {
    'name': 'Sorna',
    'valid': True
}

def authenticated(fn):
  def wrapper(*args, **kwargs):
    if args[0]['valid']== True: #if args['valid']== True:
        return fn(*args, **kwargs)
  return wrapper

@authenticated
def message_friends(user):
    print('message has been sdent')

message_friends(user1)

乍一看,authenticated 似乎能够包装 any 函数,因此必须定义 wrapper 以接受任何可能的参数组合:多个位置参数、任意关键字参数等

但是,只有 first 位置参数 args[0] 对决定是否调用原始函数(绑定到 fn)有兴趣。

设计中隐含的是 authenticated 只能安全地应用于其第一个位置参数是一个以 'valid' 作为键的可映射值的函数。

*args 始终作为元组传递,因此您需要使用索引来访问内容:

def authenticated(fn):
  def wrapper(*args, **kwargs):
    print('A', args)
    print('K', kwargs)
    if args[0]['valid']== True:
        return fn(*args, **kwargs)
  return wrapper

输出:

A ({'name': 'Sorna', 'valid': True}, )
K {}

或者,您可以将 user1 作为 kwargs 传递以摆脱索引:

def authenticated(fn):
  def wrapper(*args, **kwargs):
    print('A', args)
    print('K', kwargs)
    if kwargs['valid']== True:
        return fn(*args, **kwargs)
  return wrapper

@authenticated
def message_friends(**user):
    print('message has been sent to %s' % user['name'])

message_friends(**user1)

输出:

A ()
K {'name': 'Sorna', 'valid': True}
message has been sent to Sorna

*args 捕获传递给它的任何非关键字参数。通过调用 message_friends(user1),您将 user1 作为唯一(非关键字)参数传递,这意味着您必须通过 *args.

访问它