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

2024-04-19 12:45:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我不明白为什么我们要用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)

Tags: nametruemessagereturnifdefargswrapper
3条回答

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

但是,只有第一个位置参数args[0]在决定是否应该调用原始函数(绑定到fn)时才有意义

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

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

*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

相关问题 更多 >