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函数不熟悉的同学,也写给记性不好的自己。

 

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值