*args 和 **kwargs Python

*args and **kwargs Python

我正在做一个练习,我试图解决它,但没有结果,我不得不查看解决方案,以便有想法并重复它,这个问题,我卡住了,有点迷路了。

# Create an @authenticated decorator that only allows the function to run is user1 has 'valid' set to True:

 user1 = { 'name': 'Sorna',
           'valid': True }         #changing this will either run or not run the message_friends function.

解决方案:

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

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

message_friends(user1)

我真的不明白这部分:

if args[0]['valid']:

我的问题是 if user1 = dict,为什么我不能只使用 **kwards 这样我就可以通过仅调用 [valid] 来检查值是否为真: 它来自哪里 args[0]?

帮助,我真的被这个困住了..

如果将 user1 作为 keyword-argument 传递,则可以使用 kwargs。例如,message_friends(user_argument=user1) 将有 args == []kwargs == {'user_argument': user1}

进一步说明这一点

def my_func(*args, **kwargs):
   print(f"Args: {args}")
   print(f"Kwargs: {kwargs}")

>> my_func(1, 2, 3, 4)
Args: [1, 2, 3, 4]
Kwargs: {}

>> my_func(1, 2, three=3, four=4)
Args: [1, 2]
Kwargs: {"three": 3, "four": 4}

装饰器可以写的清楚一点不用args[0],这样对你理解有帮助吗?

def authenticated(fn):
    def wrapper(user, *args, **kwargs):
        if user['valid']:
            return fn(user, *args, **kwargs)

    return wrapper

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

message_friends({'name': 'Sorna', 'valid': True})
message_friends({'name': 'Bob', 'valid': False})

现在 *args, **kwargs 仅用于传递修饰函数可能具有的任何其他参数。

这也更稳健,因为无论 user 是按位置传递还是作为关键字参数传递,它都有效。

@authenticated 装饰器执行以下操作:

  1. 确保至少使用一个位置参数调用该函数(否则会引发异常)。
  2. 确保第一个参数是一个字典,或者至少支持通过字符串下标访问项目(同样,否则会引发异常)。
  3. 确保在字典中找到关键字 'valid'(否则,例外)。
  4. 如果键存在于字典中并且具有 True 布尔值,则调用原始函数并将其 return 值 returned装饰函数。否则,没有函数被调用,也没有值 returned.

这不是一种非常简洁的函数修饰方式,但如果您可以确保条件 1 到 3 始终成立,则条件 4 在某些情况下会很有用。