在下面的方法中, * 和** 对param2做了什么操作 ?
def foo(param1, *param2):def bar(param1, **param2):
*是指针的表示方式,记住这一点就行了,不是对参数的作用,而是规定了参数的类型,虽然指针是一个int值,但是他是一种特殊的类型。
而**也是一样,*是指针,那么**就是指针的指针,所谓的二级指针,也就是指向指针的指针。
可以这么理解,指针用来存放地址,一级指针用来存放普通变量的地址,二级指针用来存放一级指针的地址,注意,是一级指针本身的地址,不是一级指针指向的地址。
举个形象点的例子,桌子上放着一个盒子,盒子里有个变量,那么盒子放着变量,它就是变量的地址,盒子是一级指针,桌子又放着盒子,那么桌子就是盒子的地址,桌子就是二级指针,等等等等
In [1]: def foo(*args): ...: for a in args: ...: print a ...: ...: In [2]: foo(1)1 In [4]: foo(1,2,3)123
In [5]: def bar(**kwargs): ...: for a in kwargs: ...: print a, kwargs[a] ...: ...: In [6]: bar(name='one', age=27) age 27 name one
这两个习惯用法都可以与普通参数混合使用,以允许一组固定参数和一些可变参数: def foo(kind, *args, **kwargs): pass
l 习惯用法的另一个用法是在调用函数时解压参数列表。 In [9]: def foo(bar, lee): ...: print bar, lee ...: ...: In [10]: l = [1,2] In [11]: foo(*l)1 2
在 Python 3中,可以在赋值(Extended Iterable Unpacking)的左侧使用 *l,尽管在这个context中它给出的是一个列表而不是一个元组: first, *rest = [1,2,3,4] first, *l, last = [1,2,3,4]
Python 3还增加了新的语义 : def func(arg1, arg2, arg3, *, kwarg1, kwarg2): pass
这样的函数只接受3个位置参数, 之后的所有内容都只能作为关键字参数。值得注意的是,在调用函数时也可以使用 * 和 * * 。 这是一个快捷方式,允许您直接使用列表 / 元组或字典将多个参数传递给函数。例如,如果有以下代码:
def foo(x,y,z):
print("x=" + str(x))
print("y=" + str(y))
print("z=" + str(z))
可以这样做
>>> mylist = [1,2,3]>>> foo(*mylist)
x=1
y=2
z=3
>>> mydict = {'x':1,'y':2,'z':3}>>> foo(**mydict)
x=1
y=2
z=3
>>> mytuple = (1, 2, 3)>>> foo(*mytuple)
x=1
y=2
z=3
注意: mydict 中的键必须完全像函数 foo 的参数一样命名。 否则它将出现一个 TypeError:
>>> mydict = {'x':1,'y':2,'z':3,'badnews':9}>>> foo(**mydict)Traceback (most recent call last):
File "<stdin>", line 1, in <module>TypeError: foo() got an unexpected keyword argument 'badnews'
单个 * 意味着可以有任意数量的额外位置参数。 Foo ()可以像 foo (1,2,3,4,5)一样被调用。 在 foo () param2的体内是一个包含2-5的序列。
double ** 表示可以有任意数量的额外命名参数。 Bar ()可以像 bar (1,a2,b3)那样调用。 在 bar () param2的主体中是一个包含{‘ a': 2,‘ b': 3}的dictionary
用以下代码:
def foo(param1, *param2):
print(param1)
print(param2)
def bar(param1, **param2):
print(param1)
print(param2)
foo(1,2,3,4,5)
bar(1,a=2,b=3)
输出
1(2, 3, 4, 5)1{'a': 2, 'b': 3}