参考:Python3 * 和 ** 运算符 在 Python 中,* 和 ** 具有语法多义性,具体来说是有四类用法。

1. 算数运算

* 代表乘法, ** 代表乘方。

2. 函数可变参数 *args 和 **kwargs

python函数传递参数的方式有四种:

  • 位置参数(positional argument):调用函数时根据函数定义的参数位置顺序来传递参数(而不是通过指定参数名)。参数的顺序必须一一对应,且少一个参数都不可以。
  • 关键词参数(keyword argument):函数调用,通过“键-值”形式加以指定。可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。
    python的位置参数、默认参数、关键字参数、可变参数区别
  • 默认参数: 用于定义函数,为参数提供默认值,调用函数时可传可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
  • 可变参数:定义函数时,有时候我们不确定调用的时候会传递多少个参数(不传参也可以)。此时,可用包裹(packing)位置参数( *args ),或者包裹关键字参数(**kwargs ),来进行参数传递,会非常方便。
    *args 收集所有位置参数,它本质是一个 tuple
def func(*args):
	....

# func()
# func(a)
# func(a, b, c)

**kwargs 收集所有关键字参数,它本质上是一个 dict

def func(**kargs):
	....

# func(a=1)
# func(a=1, b=2, c=3)

其实并不是必须写成 *args 和 **kwargs。 *(星号) 才是必须的.你也可以写成*ar 和 **k 。而写成 *args 和**kwargs 只是一个通俗的命名约定。

如果同时使用 *args 和 **kwargs 时,必须 *args 参数列要在 **kwargs 之前。

位置参数、默认参数、可变参数的混合使用,顺序原则是:位置参数,默认参数,包裹位置参数,包裹关键字参数(定义和调用都应遵循)

def func(name, age, sex=1, *args, **kargs):
	print name, age, sex, args, kargs
	
# func('tanggu', 25, 2, 'music', 'sport', class=2)
# tanggu 25 1 ('music', 'sport') {'class'=2}

3.解包裹参数

*和**,也可以在函数调用的时候使用,称之为解包裹(unpacking)
1、在传递元组时,让元组的每一个元素对应一个位置参数

def print_hello(name, sex):
	print name, sex

# args = ('tanggu', '男')
# print_hello(*args)
# tanggu 男

2、在传递词典字典时,让词典的每个键值对作为一个关键字参数传递给函数

def print_hello(**kargs):
	print kargs

# kargs = {'name': 'tanggu', 'sex', u'男'}
# print_hello(**kargs)
# {'name': 'tanggu', 'sex', u'男'}

4. 序列解包

python可以这样赋值

a, b, c = 1, 2, 3

可以利用 * 表达式获取单个变量中的多个元素,只要它的解释没有歧义即可。例如:

# 获取剩余部分:  a=0, b=1, c=[2, 3]
a, b, *c = 0, 1, 2, 3  

# 获取中间部分: a=0, b=[1,2], c=3
a, *b, c = 0, 1, 2, 3

# 如果左值比右值要多,那么带 * 的变量默认为空
a, b, *c = 0, 1  # a=0, b=1, c=[]
a, *b, c = 0, 1  # a=0, b=[], c=1

更多序列解包参考:
Python3 序列解包

序列解包(for x,y in zip(keys, values):)详解