关于Python中*args和**kwargs的深入理解
作者:be5yond 发布时间:2021-04-07 17:45:06
目录
1. 理解 * 和 **
2.Python函数的参数
3. 支持任意参数的函数 *args, **kwargs
4. 固定位置参数和关键字参数 / *
5. **的另一个用法, 字典合并
总结:
1. 理解 * 和 **
Python的赋值语句可以解包将可迭代元素剥离出来
In [6]: a, b, c = [1, 2, 3]
In [7]: a
Out[7]: 1
In [8]: b
Out[8]: 2
In [9]: c
Out[9]: 3
赋值语句可以理解为 a, b, c = [a, b, c] = [1, 2, 3], 将变量a, b, c与目标列表中的数据进行对应.
Python中 * 和 ** 可以理解成一个特殊的解包语法. 将可迭代的对象列表字典等, 获取其中的内容.
将 * 应用到赋值语句中, 可以解包多个数据对应到一个列表变量.
In [10]: a, *other = [1, 2, 3, 4]
In [11]: a
Out[11]: 1
In [12]: other
Out[12]: [2, 3, 4]
In [13]: a, *middle, x = [1, 2, 3, 4]
In [14]: middle
Out[14]: [2, 3]
结合 print 函数理解解包, 第二个print(*['a', 'b', 'c', 'd']) 使用*号将列表解包后, 相当于print('a', 'b', 'c', 'd')
In [15]: print(['a', 'b', 'c', 'd'])
['a', 'b', 'c', 'd']
In [16]: print(*['a', 'b', 'c', 'd'])
a b c d
2.Python函数的参数
Python函数的传参, 支持两种方式, 一种是基于位置传递(Positional Arguments), 一种是基于变量名称传递(Keyword Arguments).
比如定义一个函数func 接受4个参数
In [1]: def func(a, b, c, d):
...: print(a, b, c, d)
可以基于位置传参, (1, 2, 3, 4)根据位置顺序分别赋值给参数a, b, c, d.
In [2]: func(1, 2, 3, 4)
1 2 3 4
也可以基于变量名传递参数, 指定(d=1, c=2, b=3, a=4)分别赋值给对应变量, keyword argument可以乱序
In [3]: func(d=1, c=2, b=3, a=4)
4 3 2 1
或者混合两种参数格式, 组合位置参数和关键字参数. 注意这时不能重复赋值, 即已经传递了位置参数, 不能再通过关键字传参.
In [4]: func(1, 2, d=3, c=4)
1 2 4 3
In [5]: func(1, 2, a=3, c=4)
TypeError: func() got multiple values for argument 'a'
3. 支持任意参数的函数 *args, **kwargs
然后就是我们查看源码时经常看到的语法, *args, **kwargs. 可以看到arg和kwarg即是一个变量, 目的是保存函数中的位置参数和关键字参数,成一个元组和字段对象, 保存args和kwargs就是变量名.
In [1]: def func(var, *args, key=None, **kwargs):
...: print('args: ', args)
...: print('kwargs: ', kwargs)
定义一个除了位置参数 var , 和关键字参数 key 之外还接受任意参数的函数.
调用函数时,传的其他参数就会赋值给 args, 和 kwargs.
In [2]: func('one', 'two', 'three', key='key', four=4, five=5,)
args: ('two', 'three')
kwargs: {'four': 4, 'five': 5}
In [3]: func('one', 'two', key='key', three='three', four=4, five=5,)
args: ('two',)
kwargs: {'three': 'three', 'four': 4, 'five': 5}
可以看到 'one' 赋值给了变量 var, 'two' 和 'three' 传给了元组args, 'key'赋值给了变量 four=4, five=5, 传递给了kwargs , {'four': 4, 'five': 5}.
改变three的传参方式使用three='three'之后, three也去了kwargs.
4. 固定位置参数和关键字参数 / *
Python3.8 中增加了固定参数的关键字 / 和 * , 使用/之前的参数,只能通过位置方式传参, 使用*之后的参数, 只能通过关键字方式传参.
重新写一个最开始的函数
In [1]: def func(a, /, b, *, c, d):
...: print(a, b, c, d)
其中参数a只能通过位置传递, c和d只能通过关键字传递, 参数b不做限制
In [2]: func(1, 2, c=3, d=4)
1 2 3 4
In [3]: func(1, b=2, c=3, d=4)
1 2 3 4
In [4]: func(a=1, b=2, c=3, d=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() got some positional-only arguments passed as keyword arguments: 'a'
In [5]: func(1, 2, 3, d=4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: func() takes 2 positional arguments but 3 positional arguments (and 1 keyword-only argument) were given
可以看到, 限制了参数类型之后, 传参方式错误函数会报TypeError, 应用到一些需要限制显式传递参数的场景, 可以提高代码的可读性.
5. **的另一个用法, 字典合并
3.8之后还增加了一个**的新用法, 支持在字典初始化时使用**语法. 合并现有字典的数据时, 可不使用dict.update()函数. 代码示例如下
In [1]: a = {'k': 1, 'm': 2}
In [2]: y = {'y': '3', 'z': 'ii'}
In [3]: {**a}
Out[3]: {'k': 1, 'm': 2}
In [4]: {**a, **y}
Out[4]: {'k': 1, 'm': 2, 'y': '3', 'z': 'ii'}
In [5]: {**a, **y, 'uu': 88}
Out[5]: {'k': 1, 'm': 2, 'y': '3', 'z': 'ii', 'uu': 88}
总结:
本文总结了python中*和**的使用方法, 解包时可以获取可迭代对象中的内容.
* 和**在定义函数时使用, 使得函数可以支持任意长度的参数
解包时可将任意长度数据赋值给一个对象
关键字 / 和 * 规定参数的传递方式.
生成新的字典时使用**解包其他字典中的值
来源:https://blog.csdn.net/be5yond/article/details/119357648


猜你喜欢
- 本文实例讲述了Python根据指定日期计算后n天,前n天是哪一天的方法。分享给大家供大家参考,具体如下:# -*- coding:utf-8
- 先看看CSS框架的利与弊前段时间一直在讨论CSS框架。很多朋友看了那三篇文章后提了不少自己意见。特别是一位北京的朋友A君,他有一个小的团体,
- 一、gfile模块是什么 gfile模块定义在tensorflow/python/platform/gfile.py,但其源代码实现主要位于
- 创建自定义编辑器: //引入editor_config.js,editor_api.js,ueditor.css文件,然后在body中创建编
- 在使用selenium去获取淘宝商品信息时会遇到登录界面这个登录界面处理的难度在于滑动验证的实现,有的人使用微博登录,避免了滑动验证,那可不
- 本文实例讲述了Go语言中的switch用法。分享给大家供大家参考。具体分析如下:这里你可能已经猜到 switch 可能的形式了。case 体
- 一、绘制折线图使用plot()绘制折线图常用的参数:x:表示x轴的数据y:表示y轴的数据fmt:表示快速设置条样式的格式字符串。label:
- 实现思路:分为两部分,第一部分,获取网页上数据并使用xlwt生成excel(当然你也可以选择保存到数据库),第二部分获取网页数据使用IO流将
- js的成员和方法好象没有private和public之分,列一下public的成员和方法成员:name 控件的名字,既这个控件的变量名(必选
- 问题环境依赖OS: CentOS 7.2 Python 3.5问题提出在运行一个Python程序之时,在调用sqlite之时,碰到如下的错误
- 1 基本概念1.1 命名空间 (namespace)命名空间是变量名到对象的映射(name -> obj)。目前大多数的命名空间以类似
- 1. 基本介绍tensorflow设备内存管理模块实现了一个best-fit with coalescing算法(后文简称bfc算法)。bf
- 什么是粘包问题最近在使用Golang编写Socket层,发现有时候接收端会一次读到多个数据包的问题。于是通过查阅资料,发现这个就是传说中的T
- 下载包地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python该页面下找到需要
- 1. 集合类型定义(1)集合是多个元素的无序组合集合类型与数学中的集合概念一致集合元素之间无序,每个元素唯一,不存在相同元素集合元素不可更改
- tensorlfow网络模型可视化。baidu了一些方法,现在介绍下我的流程和遇到的问题:配置window7tensorlfow1.5ana
- Python单例模式的两种实现方法方法一 import threading class Singleton(object): &
- 引言将对象的状态信息转换为可以存储或传输的形式的过程叫作序列化类似地从序列化后的数据转换成相对应的对象叫作 反序列化本文介绍 Python
- Fabric是一个用Python开发的部署工具,最大特点是不用登录远程服务器,在本地运行远程命令,几行Python脚本就可以轻松部署。文档入
- 很多朋友问过我absolute与relative怎么区分,怎么用?我们都知道absolute是绝对定位,relative是相对定位,但是这个