我们已经接触过函式 (function) 的引数 (arguments) 传递。当时我们根据位置,传递对应的引数。我们将接触更多的引数传递方式。
回忆一下位置传递:
def f(a,b,c):
return a+b+c
print(f(1,2,3))
在呼叫 f 时,1,2,3 根据位置分别传递给了 a,b,c 。
关键字传递
有些情况下,用位置传递会感觉比较死板。关键字 (keyword) 传递是根据每个引数的名字传递引数。关键字并不用遵守位置的对应关系。依然沿用上面 f 的定义,更改呼叫方式:
print(f(c=3,b=2,a=1))
关键字传递可以和位置传递混用。但位置引数要出现在关键字引数之前:
print(f(1,c=3,b=2))
引数预设值
在定义函式的时候,使用形如 a=19 的方式,可以给引数赋予预设值 (default) 。如果该引数最终没有被传递值,将使用该预设值。
def f(a,b,c=10):
return a+b+c
print(f(3,2))
print(f(3,2,1))
在第一次呼叫函式 f 时, 我们并没有足够的值,c 没有被赋值,c 将使用预设值 10.
第二次呼叫函式的时候,c 被赋值为 1,不再使用预设值。
包裹传递
在定义函式时,我们有时候并不知道呼叫的时候会传递多少个引数。这时候,包裹 (packing) 位置引数,或者包裹关键字引数,来进行引数传递,会非常有用。
下面是包裹位置传递的例子:
def func(*name):
print type(name)
print name
func(1,4,6)
func(5,6,7,1,2,3)
两次呼叫,尽管引数个数不同,都基于同一个 func 定义。在 func 的参数列中,所有的引数被 name 收集,根据位置合并成一个元组 (tuple),这就是包裹位置传递。
为了提醒 Python 引数,name 是包裹位置传递所用的元组名,在定义 func 时,在 name 前加*号。
下面是包裹关键字传递的例子:
def func(**dict):
print type(dict)
print dict
func(a=1,b=9)
func(m=2,n=1,c=11)
与上面一个例子类似,dict 是一个字典,收集所有的关键字,传递给函式 func 。为了提醒 Python,引数 dict 是包裹关键字传递所用的字典,在 dict 前加**。
包裹传递的关键在于定义函式时,在相应元组或字典前加*或**。
解包裹
*和**,也可以在呼叫的时候使用,即解包裹 (unpacking), 下面为例:
def func(a,b,c):
print a,b,c
args = (1,3,4)
func(*args)
在这个例子中,所谓的解包裹,就是在传递 tuple 时,让 tuple 的每一个元素对应一个位置引数。在呼叫 func 时使用*,是为了提醒 Python:我想要把 args 拆成分散的三个元素,分别传递给 a,b,c 。(设想一下在呼叫 func 时,args 前面没有*会是什么后果?)
相应的,也存在对词典的解包裹,使用相同的 func 定义,然后:
dict = {‘a’:1,’b’:2,’c’:3}
func(**dict)
在传递词典 dict 时,让词典的每个键值对作为一个关键字传递给 func 。
混合
在定义或者呼叫引数时,引数的几种传递方式可以混合。但在过程中要小心前后顺序。基本原则是,先位置,再关键字,再包裹位置,再包裹关键字,并且根据上面所说的原理细细分辨。
注意:请注意定义时和呼叫时的区分。包裹和解包裹并不是相反操作,是两个相对独立的过程。
总结
关键字,预设值,
包裹位置,包裹关键字
解包裹
文章来自互联网博客网站, 作者:Vamei 出处:http://www.cnblogs.com/vamei