Python定义函数时,不同参数类型的传递

python的底层是通过C语言实现,因此参数调用时是通过地址传递的(和C语言一样,值是单向传递,指针才能实现双向传递),比如:


# -*- coding: utf-8 -*-
def f1(x,y):
z=x+y
  return z

b=2
c=f1(a, b)
print c, a, b

得到的结果是

3 1 2

从这里可以看出b值并没有变化,也就是说值是单向传递的。

函数的定义时,参数可以是数值,列表(当元组处理),字典等,其参数定义形式如下:

def f(a, *pargs, **kargs): 
    print(a, pargs, kargs)

实际上这是python的很重要的一个特性,即arbitrary arguments。当你需要一个函数支持任意多个参数的时候,你就会用到它。上面例子中的那个函数,python会把匹配上的参数作为一个tuple(元祖)来处理。可以像下面这样调用函数f,

f(1, 3, 'abc', ('lls', 'pow'), param1 = 'A')

打印出来结果如下:

(1, (3, 'abc', ('lls', 'pow')), {'param1': 'A'})

python会把1匹配给参数a,把3, 'abc', ('lls', 'pow')匹配给pargs,可以看出pargs被用tuple (3, 'abc', ('lls', 'pow'))赋值。
类似的,前面出现两个星号的kargs会被用字典匹配,即所有像param = x这种格式的传入参数会被转成dict赋值给给kargs。

需要注意的是,在定义函数的时候**kargs这种类型的参数必须放在最后(如果有的话),而*pargs这种类型的参数必须放在**kargs这种类型参数的前面,其他类型参数的后面。
比如下面这几种定义都是非法的

def f(a, *b, c=6, **d):
    pass
def f(a, **b, *c):
    pass
def f(*a, **b, c):
    pass
def f(a, b, *c, **d, e):
    pass

而下面这几种定义都是合法的

def f(a, **b):
    pass
def f(a, *b):
    pass
def f(*a, **b):
    passs
def f(**a):
    pass
def f(a, b=1, *c, **d):
    pass

举一个实际一点的例子,写一个函数,输入任意多个数字作为参数,找到其中最大的一个,就可以利用我们提到的*pargs, 代码如下:

1 def max(*pargs):
2     maxNum = pargs[0]
3     for i in pargs[1:]:
4         if i > maxNum:
5             maxNum = i
6     return maxNum
7 
8 print max(5, 3, 1, 43, 54, 23, 1, 2, 32)

结果打印54。

参考博文:http://blog.chinaunix.net/uid-29466937-id-5752171.html