>>> def print_params(x,y,z=3,*pospar,**keypar):
print x,y,z
print pospar
print keypar
>>> print_params(1,2,3,5,6,7,foo=1,bar=2)
1 2 3
(5, 6, 7)
{'foo': 1, 'bar': 2}
>>> print_params(1,2)
1 2 3
()
{}
请仔细体味上面的例子,前三个参数是固定的,第四个参数pospar是位置参数,可以收集多个参数,第五个参数是关键字参数,可以收集多个关键字参数。当没有输入时,默认为空元组或者空字典。
2.4 反转过程
刚刚已经讨论过如何将参数收集为元组和字典了,如果使用*和**的话,还可以执行相反的操作。(1)在调用的时候使用
复制代码 代码如下:
>>> def add(x,y):
return x+y
>>> params =(1,2)
>>> add(*params)
3
(2)在定义的时候使用
复制代码 代码如下:
>>> def with_stars(**kds):
print kds['name'],'is',kds['age'],'years old'
>>> args = {'name':'Mr.Gumby','age':42}
>>> with_stars(**args)
Mr.Gumby is 42 years old
三. 作用域
在执行x=1赋值语句后,名称x引用到值1。这就像用字典一样,键引用值,当然,变量和所对应的值用的是个‘不可见'的字典。内建vars函数可以返回这个字典:
复制代码 代码如下:
>>> x=1
>>> scope = vars()
>>> scope['x']
1
>>> scope['x'] += 1
>>> x
2
这个不可见的字典叫做命名空间或者作用域。除了全局作用域外,每个函数调用都会创建一个新的作用域。
一般学过编程的基本都知道什么是作用域了,这里就不细讲了。
四. 递归
递归的定义包括它们自身定义内容的引用。
一个有用的递归函数包含以下几部分:
(1)当函数直接返回值时有基本实例(最小可能性问题)
(2)递归实例,包括一个或者多个问题最小部分的递归调用。
这里的关键是将问题分解为小部分,递归不能永远继续下去,因为它总是以最小可能性问题结束,而这些问题又存储在基本实例中。
下面我们来看3个经典的递归例子:
A.阶乘
>>> def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n-1)
[/code]
B.幂
复制代码 代码如下:
>>> def power(x,n):
if n == 0:
return 1
else:
return x * power(x,n-1)
C.二元查找(假设number必然在序列sequence中)
复制代码 代码如下:
>>> def search(sequence,number,lower,upper):
if lower == upper:
assert num == sequence[upper]
return upper
else:
middle = (lower+upper) // 2
if number > sequence[middle]:
return search(sequence,number,middle+1,upper)
else:
return search(sequence,number,lower,middle)