Python函数参数全攻略——(*args与**kwargs参数的用法)位置参数、关键字参数、收集参数与分配参数

目录

 

1. 位置参数与关键字参数

2. 收集参数(*args与**kwargs参数)

3. 分配参数


1. 位置参数与关键字参数

参数的概念都是与函数息息相关的。其中def语句中,位于函数名后面的变量通常称为形参,而调用函数时提供的值称为实参。一般情况下不对此进行严格区分。

在了解收集参数前(*args与**kwargs参数)要知道位置参数与关键字参数的含义。位置参数就是根据位置,进行实参到形参的值传递匹配。如下:

def hello(greeting, name):
    print('{},{}!'.format(greeting, name))

>>>hello('Hello', 'World')
Hello,world!

 有时候,参数的排列顺序可能很难记住,尤其是参数很多的时候,为了简化调用工作,可指定参数的名称,即将参数赋予关键字。如下:

def hello(greeting, name):
    print('{},{}!'.format(greeting, name))

>>>hello(greeting='Hello', name='World')
Hello,world!

>>>hello(name='World', greeting='Hello')
Hello,world!

 此时,参数的顺序无关紧要。像这样使用名称指定的参数称为关键字参数,主要有点是有助于澄清各个参数的作用。及时输入参数多些,每个参数的作用也很明确。另外,参数顺序错了也没关系。然而,关键字参数最大的优点在于,可以指定默认值。

def hello(greeting='Hello', name='World'):
    print('{},{}!'.format(greeting, name))

 像这样给参数指定默认值后,调用函数是可以不提供它!可以根据需求,一个参数值都不提供、提供部分参数值或者提供全部参数值。

2. 收集参数(*args与**kwargs参数)

温馨提示argsarguments 的缩写,参数的意思;kwargskeywords arguments 的缩写,关键字参数的意思。】

有时候,用户需要提供任意数量的参数。实际上,实现起来并不困难,仅需要像这样定义函数:

def print_params(*arg):
    print(arg)

这里好像只指定了一个参数,但它的前面有一个星号。可以尝试调用一下,一探究竟。

>>>print_params('Testing')
('Testing',)

>>>print_params(1, 2, 3)
(1, 2, 3)

 不难发现,打印的是一个元组。也就是说,前面有星号的参数将被放在元组中,也就是将这些值收集起来。带星号的参数可以放在多个形参的后面(此时它收集其他形参没有收集的值),也可以放在前面或者中间,不过此时会麻烦点,如下:

def in_the_middle(x, *y, z):
    print(x, y, z)

>>>in_the_middle(1, 2, 3, 4, 5, 6, z=7)
1 (2, 3, 4, 5, 6) 7

 可见,如果带星号形参放在前面或者中间,则它后面的参数则需要使用名称指定,类似关键字参数。

另外,单星号参数(*arg)是不会收集关键字参数的,要收集关键字参数,就要使用两个星号。

def print_params_2(**kwargs):
    print(kwargs)

>>>print_params_2(x=1, y=2, z=3)
{'z':3, 'x:1, 'y':2}

可见,这样得到的是一个字典而不是元组。 讲这些参数形式结合:

def print_params_3(x, y, z=3, *args, **kwargs):
    print(x, y, z)
    print(args)
    print(kwargs)

>>>print_params_3(1, 2, 3, 4, 5, 6, 7, foo=1, bar=2)
(1, 2, 3)
(4, 5, 6, 7)
{'foo':1, 'bar':2}

>>>priint_param_3(1, 2)
1 2 3
()
{}

3. 分配参数

 前面介绍了如何将参数收集到元组或者字典中,但使用同样的两个运算符(*和**)也可以执行相反的操作,即将参数分配传递给形参,恰好与收集实参传递的参数的操作相反。如下:

def add(x, y):
    return x+y

#同时假设存在一个元组,包含两个要加的数
params = (1, 2)

>>>add(*params)
3

这与前面执行的操作差不多是相反的:不是收集参数,而是分配参数。这是通过在调用函数(而不是定义函数)时实现的。这猴子那个做法也可以用于参数列表的一部分,条件是这部分位于参数列表末尾。通过使用**可将字典中的值分配给关键字参数。如下:

def hello(greeting='Hello', name='World'):
    print('{},{}!'.format(greeting, name))

params = {'name':'Song', 'greeting':'Well met'}

>>>hello(**params)
Well met,Song!

 最后,给一个忠告,虽然星号*和双星号**,既可以使用在定义函数又可以使用在调用函数时,但非常不建议同时使用。如果同时使用,将值传递元组(列表也可以!!)或者字典。因此还不如不用它们,不用还能省去些许麻烦。

【提示】单星号分配参数也可以是列表(搭建深度学习网络遇到了),下面是测试证明(不好意思,急于验证手头只有pad了),如下:

这篇文字,写给对python函数不熟悉的同学,也写给记性不好的自己。

 

Python 函数中,斜杆(`/`)、`*args` 和 `**kwargs` 是用于处理函数参数的特殊语法,它们各自有不同的用途和原理。 ### 斜杆(`/`) 在 Python 3.8 及以后的版本中,函数参数列表里可以使用斜杆(`/`)来指明某些参数只能以位置参数的形式传入,不能使用关键字参数的形式。例如: ```python def func(a, b, /, c): return a + b + c # 正确的调用方式 print(func(1, 2, 3)) # 错误的调用方式 # print(func(a=1, b=2, c=3)) ``` 这里,`a` 和 `b` 只能通过位置来传递,而 `c` 既可以用位置参数也可以用关键字参数传递。 ### `*args` `*args` 用于将不定数量的位置参数打包成一个元组。在函数定义时,`*` 是一个打包操作符,它会把传递给函数的所有额外位置参数收集到一个元组中。示例如下: ```python def sum_numbers(*args): total = 0 for num in args: total += num return total print(sum_numbers(1, 2, 3, 4)) ``` 在这个例子中,`*args` 收集了 `1, 2, 3, 4` 这些位置参数,形成一个元组 `(1, 2, 3, 4)` 供函数内部使用。 ### `**kwargs` `**kwargs` 用于将不定数量的关键字参数打包成一个字典。在函数定义时,`**` 是一个打包操作符,它会把传递给函数的所有额外关键字参数收集到一个字典中。示例如下: ```python def print_info(**kwargs): for key, value in kwargs.items(): print(f"{key}: {value}") print_info(name="Alice", age=25, city="New York") ``` 在这个例子中,`**kwargs` 收集了 `name="Alice", age=25, city="New York"` 这些关键字参数,形成一个字典 `{'name': 'Alice', 'age': 25, 'city': 'New York'}` 供函数内部使用。 ### 同时使用 `*args` 和 `**kwargs` 同时使用 `*args` 和 `**kwargs` 时,`*args` 参数必须在 `**kwargs` 参数之前。如果违反这个规则,会提示语法错误“SyntaxError: non-keyword arg after keyword arg” [^1]。示例如下: ```python def func(*args, **kwargs): print("Positional arguments:", args) print("Keyword arguments:", kwargs) func(1, 2, 3, a=4, b=5) ``` ### 解包操作 在调用函数时,`*` 和 `**` 也可以作为解包操作符使用。`*` 用于解包可迭代对象(如列表、元组等)为位置参数,`**` 用于解包字典为关键字参数。例如: ```python def add(a, b): return a + b numbers = [1, 2] print(add(*numbers)) params = {'a': 3, 'b': 4} print(add(**params)) ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值