Python * args和** kwargs
时间:2020-02-23 14:42:26 来源:igfitidea点击:
Python函数参数
Python允许我们为函数定义三种类型的参数:
- 形式参数,例如
def add(a,b)
- 使用* args的可变数量的非关键字参数,例如
def add(* args)
- 可变数量的关键字参数或者使用** kwargs命名的参数,例如
def add(** kwargs)
。
有关函数参数的一些重要点。
当定义函数参数时,顺序应为形式参数,后跟* args和** kwargs。
不必使用args和kwargs这两个名称,我们也可以使用其他名称。
但是,惯例是使用它们。
这将使您的代码易于阅读和理解。args变量的类型为tuple。
我们可以将元组作为函数参数传递给args进行映射。kwargs变量的类型为dict。
因此,我们可以将字典作为参数传递给kwargs。
为什么我们需要* args和** kwargs?
假设我们有一个将两个数字相加的函数:
def add_two_numbers(a, b): return a + b
现在我们要扩展它以添加三个数字。
我们不能只更改此功能,因为它可能会在其他地方使用,这将是一个重大突破。
因此,我们引入了另一个函数,将三个数字相加。
def add_three_numbers(a, b, c): return a + b + c
你知道我要去其中了吧?由于我们可以为函数指定可变数量的参数,因此我们可以定义一个通用函数来添加数字。
Python * args示例
让我们定义一个通用函数,使用* args变量添加数字。
def add(*args): total = 0 for arg in args: total = total + arg return total print(add(1, 2)) print(add(1, 2, 3)) print(add(1, 2, 3, 4))
* args和** kwargs是什么类型?
def zap(*args, **kwargs): print(type(args)) print(type(kwargs)) zap()
输出:
<class 'tuple'> <class 'dict'>
Python ** kwargs示例
我们定义一个函数来显示** kwargs变量的用法。
def kwargs_processor(**kwargs): for k, v in kwargs.items(): print(f'Key={k} and Value={v}') kwargs_processor(name='hyman', age=34) kwargs_processor(country='San Franceco', capital='New Delhi')
输出:
Key=name and Value=hyman Key=age and Value=34 Key=country and Value=San Franceco Key=capital and Value=New Delhi
为* args和** kwargs映射传递元组和字典
让我们看看如何将元组值与args和dictionary元素映射到kwargs变量。
t = (10, 30, 60) print(add(*t)) d = {'name': 'hyman', 'age': 34} kwargs_processor(**d)
输出:
100 Key=name and Value=hyman Key=age and Value=34
注意在使用元组将其值映射到args时使用*。
同样,**用于将dict元素映射到kwargs变量。
何时使用* args和** kwargs
您可以在期望可变数量参数的任何函数中使用它们。
但是,它们在两种特定情况下非常有用–模拟函数响应和编写通用装饰函数。
用* args和** kwargs模拟函数响应
假设我们有一个如下定义的API类:
class APIHelper: def call_api(self, url, input_json): # some complex logic return 'complex_response_data'
我们可以创建一个测试模拟器函数并将其映射到API函数以生成测试响应。
class MyTestClass: def test_call_api(self, *args, **kwargs): return "test_response_data" # Assign API function to use our test function APIHelper.call_api = MyTestClass.test_call_api
让我们看看现在使用API函数时会发生什么。
ah = APIHelper() print(ah.call_api()) print(ah.call_api(1, url='https://www.theitroad.local', input_json={})) print(ah.call_api(1, 2, url='https://www.theitroad.local'))
输出:
test_response_data test_response_data test_response_data
* args和** kwargs的装饰函数
让我们看看如何定义装饰器函数来记录函数变量。
def log_arguments(func): def inner(*args, **kwargs): print(f'Arguments for args:{args}, kwargs:{kwargs}') return func(*args, **kwargs) return inner
现在,我们可以将此装饰器函数与任何其他函数一起使用,以将其参数记录到控制台。
@log_arguments def foo(x, y, z): return x + y + z sum_ints = foo(1, 2, z=5) print(sum_ints) @log_arguments def bar(x, *args, **kwargs): total = x for arg in args: total = total + arg for key, value in kwargs.items(): total = total + value return total sum_ints = bar(1, 2, 3, a=4, b=5) print(sum_ints)
输出:
Arguments for args:(1, 2), kwargs:{'z': 5} 8 Arguments for args:(1, 2, 3), kwargs:{'a': 4, 'b': 5} 15