函数的参数类型:位置参数(必选参数+默认参数)、默认参数、可变参数、关键字参数、命名关键字参数
位置参数:调用函数时,传入的两个值按照位置顺序依次赋给参数x
和n
。
定义一个函数,计算X的n次方,让n=n-1这个想法很好:
def power(x,n):
sum=1
while n>0:
n=n-1
sum=sum*x
return sum
print(power(5,2))
执行结果正确:25
默认参数:给参数设置一个默认值:
def power(x,n):
sum=1
while n>0:
n=n-1
sum=sum*x
return sum
print(power(5))
print(power(5))
TypeError: power() missing 1 required positional argument: 'n'
执行结果报错:少一个位置参数n
修改程序如下:
def power(x,n=2):
sum=1
while n>0:
n=n-1
sum=sum*x
return sum
print(power(5))
print(power(5,3))
25
125
执行结果就正确了,
当我们调用power(5)
时,相当于调用power(5, 2)
:
从上面的例子可以看出,默认参数可以简化函数的调用。设置默认参数时,有几点要注意:
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数。
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
def enroll(name,gender,age='6',city="Beijing"):
print('name:',name,"gender:",gender,"age:",age,"city:",city)
enroll('Jony','男')
enroll('Tom','女',city='Shanghai')
enroll('Tommy','男','Bengjing','6')
执行结果:
name: Jony gender: 男 age: 6 city: Beijing
name: Tom gender: 女 age: 6 city: Shanghai
name: Tommy gender: 男 age: Bengjing city: 6
只有与默认参数不符的学生才需要提供额外的信息,如:
enroll('Tom',20,city='Shanghai')
如果不指定参数名=参数值,函数会按照参数定义的顺序取值,如:
enroll('Tommy','男','Bengjing','6')
最后把年龄显示成Beijing,把city显示成6
可变参数:可变参数就是传入的参数个数是可变的,可以是1个、2个到任意个,还可以是0个,
def calc(numbers):
sum=0
for n in numbers:
sum=sum+n*n
return sum
print(calc([1,2,3,4])) #一个List
print(calc((1,2,3,4,5,6))) #一个tuple
执行结果:
30
91
改造下:
def calc(*numbers):
sum=0
for n in numbers:
sum=sum+n*n
return sum
print(calc(1,2,3,4,5,6))
print(calc(1,2))
print(calc())
执行结果:
91
5
0
定义可变参数和定义一个list或tuple参数相比,仅仅在参数前面加了一个*
号。在函数内部,参数numbers
接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数
疑问:tuple不是不可变的吗?难道与前面的tuple每一个元素不可变才是真正的不可变类似的原理????
关键字参数:允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict,它可以扩展函数的功能,保证接收到必选参数,如果愿意加入更多参数也可以
def person(name,age,**kw):
print('name:',name,'age:',age,'other:',kw)
person('Michael',30) #函数person除了必选参数name和age外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:
person('Job',45,city="Beijing") #任意个数的关键字参数:
person('Tom',23,gender='M',city='Shanghai') #任意个数的关键字参数:
执行结果:
name: Michael age: 30 other: {}
name: Job age: 45 other: {'city': 'Beijing'}
name: Tom age: 23 other: {'gender': 'M', 'city': 'Shanghai'}
和可变参数类似,也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去
extra={'city':'Beijing','job':'Engineer'}
person('Jack',25,**extra)
执行结果:name: Jack age: 25 other: {'city': 'Beijing', 'job': 'Engineer'}
命名关键字参数:给关键字参数命名一个具体的名称
def person(name,age,*,city,job):
print(name,age,city,job)
person('Jack',24)
执行结果:
person('Jack',24)
TypeError: person() missing 2 required keyword-only arguments: 'city' and 'job'
报错:提示丢失了两个必要的关键字参数city和job
def person(name,age,*,city,job):
print(name,age,city,job)
person('Tommy',26,'Beingjing','Enginner')
执行结果:
person('Tommy',26,'Beingjing','Enginner')
TypeError: person() takes 2 positional arguments but 4 were given
报错:定义了2个位置参数,但是调用时用了4个
def person(name,age,*,city,job):
print(name,age,city,job)
person('Tome',25,city='Shanghai',job='Engnner')
执行结果:
Tome 25 Shanghai Engnner
结果终于正确了,总结:1、命名关键字参数必须传入参数名,这和位置参数不同。如果没有传入参数名,调用将报错
2、和关键字参数**kw
不同,命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数。命名关键字参数在调用时,必须传入;
3、如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了:
def person(name,age,*args,city,job):
print(name,age,city,job)
person('Tome',25,city='Shanghai',job='Engnner')
执行结果:
Tome 25 Shanghai Engnner
4、命名关键字参数有默认值的时候,可以有缺省值
def person(name,age,*,city='Beijing',job):
print(name,age,city,job)
person('Tome',25,job='Engnner')
执行结果:由于命名关键字参数city
具有默认值,调用时,可不传入city
参数
Tome 25 Beijing Engnner
参数组合:
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差