函数的参数问题
Python中函数的参数包括位置参数,默认参数,可变参数,关键字参数,命名关键字参数。
1 位置参数
位置参数即必选参数。若调用函数时没有传入位置参数,则会出现 TypeError
def func(a):
print('hello')
func()
TypeError Traceback (most recent call last)
<ipython-input-2-bd1982955a12> in <module>()
----> 1 func()
TypeError: func() missing 1 required positional argument: 'a'
2 默认参数
默认参数必须放在位置参数后面。
默认参数必须指向不变对象!
def add_end(L = []):
L.append('end')
print(L)
add_end()
add_end()
['end']
['end', 'end']
默认参数是 []
,但是函数似乎每次都“记住了”上次添加了'end'
后的list。
原因解释如下:
Python函数在定义的时候,默认参数L
的值就被计算出来了,即 []
,因为默认参数 L
也是一个变量,它指向对象 []
,每次调用该函数,如果改变了L
的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的 []
了。
要修改上面的例子,可以使用 None
这个不可变对象:
def add_end(L = None):
if L is None:
L = []
L.append('end')
print(L)
add_end()
add_end()
['end']
['end']
3 可变参数
不确定待传入的参数个数时,可以使用可变参数。
在函数内部,可变参数以元组接收。
def my_sum(*arg):
sum = 0
for i in arg:
sum = sum + i*i
print(sum)
my_sum(1,3,5)
my_sum(*[2,4,6])
35
56
4 关键字参数
可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def student(name, age=14, **kwarg):
print('name:{0},age:{1},other:{2}'.format(name,age,kwarg))
student('Bob',14, math=99, English=100)
grade = {'math':98, 'English': 97}
student('Lily', **grade)
name:Bob,age:14,other:{'math': 99, 'English': 100}
name:Lily,age:14,other:{'math': 98, 'English': 97}
关键字参数可以扩展函数的功能。比如我们正在做学生注册的功能,除了姓名和年龄是必填之外,可以利用关键字参数扩展注册的需求。
5 命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过 kwarg 检查。
如果要限制关键字参数的名字,就可以用命名关键字参数。
def student(name, age=14, *, math, English):
print(name, age, math, English)
student('July', 15, math=100, English=100)
July 15 100 100
和关键字参数**kwarg
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。
命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错.
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了:
def student(name, age=14, *arg, math, English):
print(name, age, arg, math, English)
student('Sandy', 15, 'F', math=92, English=100)
Sandy 15 ('F',) 92 100