*
和**
-
test(*args)
*
的作用其实就是把序列args中的每个元素,当作位置参数传进去。*
所对应的形参会被解释为一个元组
def show_1(*args):
print(args)
def show(*args):
print(args,type(args))
show_1(args)
show_1(*args)
show(1,2)
# (1, 2)
# ((1, 2),)
# (1, 2)
-
test(**kwargs)
**
的作用则是把字典 kwargs 变成关键字参数传递。**
所对应的形参(如上面的b)会被解释为一个字典 非关键字传递的变量必须写在关键字传递变量的前面,所以混合使用
*
和**
时*
形参在**
形参的前面 。-
解包裹
把元组或字典作为参数传入时,如果要适配包裹形式的形参定义,按照元组用
*
,字典用**
的方式“解包裹”传递即可。
传参机制
-
所有的参数实际上都是通过指针进行传递的,作为参数被传递的对象从来不自动拷贝
-
不可变参数“通过值”进行传递
整数和字符串这样的对象是不可变对象,它们通过对象引用而不是拷贝进行传递的,但是因为无论如何都不可能在原处改变不可变对象,实际的效果就很像创建了一份拷贝
-
可变对象是通过“指针”进行传递的
列表和字典这样的对象也是通过对象引用进行传递的,这一点与C语言使用指针传递数组很相似,可变对象能够在函数内部进行原处的改变,这一点和C数组很像
-
不管什么类型的参数,在 Python 函数中对参数直接使用“=”符号赋值是没用的,直接使用“=”符号赋值并不能改变参数。
如果需要让函数修改某些数据,则可以通过把这些数据包装成列表、字典等可变对象,然后把列表、字典等可变对象作为参数传入函数,在函数中通过列表、字典的方法修改它们,这样才能改变这些数据。
-
参数顺序
位置参数 ---> 默认参数 ---> 变长参数 ---> 关键字参数 ---> 命名关键字参数