1. 函数的参数
必选参数、默认参数、可变参数和关键字参数
位置参数
def power(x):
return x * x;
默认参数
def power(x,n=2):
return x * n;
def power(name,gender,age=7,city="Beijing"):
print('city:',city)
多个默认参数,调用时.
1.按顺序提供默认参数,power('Bob','M',7),city参数没提供,仍然用默认值
2.不按照顺序提供部分默认值,需要把参数名写上,power('Bob','M',city='Tianjin')
默认参数的坑
传入一个list,添加一个END再返回:
def add_end(L=[]):
L.append("END")
return L
正常调用和使用默认参数调用时,都是对的
>>> add_end([1, 2, 3])
[1, 2, 3, 'END']
>>> add_end()
['END']
但是,再次调用add_end()时,结果就不对了。
>>> add_end()
['END', 'END']
>>> add_end()
['END', 'END', 'END']
原因解释如下:
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变L的内容,则下次调用时,默认参数的内容就变了,不在是函数定义时的[]了。
定义默认参数要记牢:默认参数必须指向不变对象!!!
要修改上面的例子,我们可以用None这个不变对象来实现。
def add_end(L=None):
if L is None:
L=[]
L.append('END')
return L
为什么要设计str,None这样的不变对象呢?
因为不变对象一旦建立,对象内部的数据就不能改变,这样就减少了由于修改数据导致的错误,此外,由于对象不变,多任务环境下同时读取对象不需要加锁。
可变参数
1.由于参数个数不确定,可以作为一个list或者tuple传过来
def calc(numbers):
sum=0
for n in numbers:
sum+=n
return sum
>>>calc([1,2,3])
6
>>>calc((1,3,5))
9
2.利用可变参数,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
>>>calc(1,2,3)
6
>>>calc(1,3,5)
9
关键字参数
可变参数允许传入0或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许传入0或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name,age,**kw):
print('name:', name, 'age:', age, 'other:', kw)
>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
命名关键字参数
如果限制关键字参数的名字,就可以用命名关键字参数。*后面的参数被视为命名关键字参数。
def person(name,age,*,city,job):
print(name, age, city, job)
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
命名关键字参数必须传入参数名,这和位置参数不同,如果没有传入参数名,调用将会报错
参数组合
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
总结
1.默认参数一定要用不可变对象.
2.args:可变参数,接收的是一个tuple
3.*kw:关键字参数,kw接收的是一个dict
2.递归函数
如果一个函数在内部调用自身本身,这个函数就是递归函数。
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
网友评论