1. 包裹传参
首先思考一个问题: 为什么要有包裹传参? 原因包括但不仅限于以下两点:1不确定参数的个数.2希望函数定义的更加松散灵活
包裹传参分两种: 包裹位置传参和包裹关键字传参. 先看包裹位置传参:
在这里, 如果先说定义肯定有些晦涩难懂, 我们直接看下面这个例子吧!
- def package_position(*all_arguments):
- print(type(all_arguments))
- print(all_arguments)
这里定义了一个函数 package_position(), 其传入参数与一般的参数不一样, 前面有一个 * 号, 表明这是一个包裹, 接下来调用的时候如下:
- package_position(1, 4, 6)
- package_position(5, 6, 7, 1, 2, 3)
那么打印的结果呢, 是这样的:
根据函数的定义, 我们知道, 打印的第一行是传入的参数的类型(即 type), 根据打印结果, 我们知道这是一个 tuple, 即元祖类型. 也就是说, 当我们在调用这个方法的时候, 传入的参数 1,4,6, 最后全部包在一起, 封装成一个 tuple, 传递给函数内部. 打印的第二行, 就是该元祖的内容. 然后, 根据打印结果的第二行, 我们可以知道, 这就是我们在调用时传入的 1,4,6.
总结一下: 在调用 package_position()时, 所有的数据都根据先后顺序, 收集到一个元祖, 在函数内部, 我们可以通过元祖来读取传入的数据, 这就是包裹位置传参.
再来看看什么时包裹关键字传参:
有了以上包裹位置传参, 那么包裹关键字传参就不多说了, 还是直接看例子:
- def package_keyword(**all_arguments):
- print(type(all_arguments))
- print(all_arguments)
- package_keyword(a = 1, b = 9)
- package_keyword(m = 2, n = 1, c = 11)
与上面一个例子类似, 当函数调用时, 所有参数会收集到一个数据容器里. 只不过, 在包裹关键字传递的时候,, 数据容器不再是一个元祖, 而时一个字典. 每个关键字形式的参数调用, 都会成为字典的一个元素. 参数名为元素的键, 而数据成为元素的值. 字典 all_arguments 收集了所有的参数, 把数据传递给函数使用. 为了提醒, 参数 all_arguments 是包裹关键字传递所有的字典, 因此在 all_arguments 前加 **. 打印结果如下:
2. 解包裹
除了用于函数定义,* 和 ** 还可用于函数调用. 这时候, 两者是为了实现一种叫作解包裹 (unpacking) 的语法. 解包裹允许我们把一个数据容器传递给函数, 再自动地分解为各个参数. 需要注意的是, 包裹传参和解包裹并不是相反操作, 而是两个相对独立的功能(但给人的感觉就是两个相反的操作). 下面是解包裹的一个例子:
- def unpackage(a, b, c):
- print(a, b, c)
- args = (1, 3, 4)
- unpackage(*args)
- args = {"a":1, "b":2, "c":3}
- unpackage(**args)
根据上面的代码, 估计读者也大概知道了关于解包裹的概念. 我们调用函数时传递的是一个元祖, 按照基本传参的方式, 一个元祖是无法和三个参数对应上的. 但我们通过在 args 前加上 * 符号, 来提醒 Python, 我想把元祖拆成三个元素, 每一个元素对应函数的一个位置参数. 于是, 元祖的三个元素分别赋予了三个参数.
相应的, 词典也可用于解包裹(上述代码第 7,8 行). 在传递词典 args 时, 让词典的每个键值对作为一个关键字传递给函数.
来源: https://www.cnblogs.com/HeZhengfa/p/10296508.html