Python中的函数参数(位置参数、默认参数、可变参数)⽬录
⼀、位置参数
⼆、默认参数
三、可变参数
四、关键字参数
五、命名关键字参数
六、各种参数之间的组合
函数的参数:Python中函数定义⾮常简单,由于函数参数的存在,使函数变得⾮常灵活应⽤⼴泛;不但使得函数能够处理复杂多变的参数,还能简化函数的调⽤。
Python中的函数参数有如下⼏种:位置参数、默认参数、可变参数、关键字参数和命名关键字参数
⼀、位置参数
位置参数(positional arguments)就是其他语⾔的参数,其他语⾔没有分参数的种类是因为只有这⼀种参数,所有参数都遵循按位置⼀⼀对应的原则。
计算x^2 的函数:
def power(x):
return x * x
power(2)
对于power(x) 函数,参数x就是⼀个位置参数,也叫做必选参数。当我们调⽤power函数时,必须传⼊有且仅有的⼀个参数x。
现在,如果我们要计算 x^3 怎么办?可以再定义⼀个power3 函数,但是如果要计算 x^4 、 x^5 ……怎么办?我们不可能定义⽆限多个函数。
你也许想到了,可以把power(x) 修改为power(x, n) ,⽤来计算 x^n ,说⼲就⼲:
def power(x,n):
s = 1
while n > 0:
s = s*x
n = n-1
return s
对于这个修改后的power(x, n) 函数,可以计算任意n次⽅
print(power(2,10))
print(power(1,10))
输出:
1024
1
修改后的power(x, n) 函数有两个参数:x和n,这两个参数都是位置参数,调⽤函数时,传⼊的两个值按照位置顺序依次赋给参数x 和n 。
⼆、默认参数
由于我们经常计算 x^2 ,所以,完全可以把第⼆个参数n 的默认值设定为2,这个时候,默认参数就派上⽤场了。
def power(x,n=2):
s = 1
while n > 0:
s = s*x
n = n-1
return s
print(power(4))
print(power(3,n=3))
print(power(2,4))
输出:
16
27
16
这样,当我们调⽤power(4) 时,相当于调⽤power(4, 2) :⽽对于n > 2 的其他情况,就必须明确地传⼊n ,⽐如power(2, 4) 。
从上⾯的例⼦可以看出,默认参数可以简化函数的调⽤。
设置默认参数时,有⼏点要注意:
1、必选参数(位置参数)在前,默认参数在后,否则Python的解释器会报错
2、当函数有多个参数时,把变化⼤的参数放前⾯,变化⼩的参数放后⾯。变化⼩的参数就可以作为默认参数
使⽤默认参数有什么好处?
举个例⼦,我们写个⼀年级⼩学⽣注册的函数,需要传⼊name 、gender 、age、city四个参数:
python新手函数由于⼤多数学⽣注册时年龄和城市基本⼀样,就可以把年龄和城市设置为默认参数,这样,⼤多数学⽣注册时不需要提供年龄和城市,只提供必须的两个参数,只有与默认参数不符的学⽣才需要提供额外的信息。
#学籍输⼊
def enroll(name,gender,age=6,city='BJ'):
print('name is: ',name)
print('gender is: ',gender)
print('age is: ',age)
print('city is: ',city,'\n')
enroll('Tom','M')
enroll('Lisa','f')
enroll('Bob','M',7)
enroll('Lucy','F',7,'TJ')
enroll('Jerry','M',city='SH')
输出:
name is: Tom
gender is: M
age is: 6
city is: BJ
name is: Lisa
gender is: f
age is: 6
city is: BJ
name is: Bob
gender is: M
age is: 7
city is: BJ
name is: Lucy
gender is: F
age is: 7
city is: TJ
name is: Jerry
gender is: M
age is: 6
city is: SH
可见,默认参数降低了函数调⽤的难度,⽽⼀旦需要更复杂的调⽤时,⼜可以传递更多的参数来实现。⽆论是简单调⽤还是复杂调⽤,函数只需要定义⼀个。
注意:默认参数有个最⼤的坑,演⽰如下:
先定义⼀个函数,传⼊⼀个list,添加⼀个end 再返回:
def add_end(list=[]):
list.append('end')
return list
当你正常调⽤时,结果似乎不错:
print(add_end([1,2,3]))
print(add_end(['x','y']))
输出:
[1, 2, 3, 'end']
['x', 'y', 'end']
#当你使⽤默认参数调⽤时,⼀开始结果也是对的:
print(add_end())
#但是,再次调⽤add_end() 时,结果就不对了:
print(add_end())
print(add_end())
输出:
['end']
['end', 'end']
['end', 'end', 'end']
很多初学者很疑惑,默认参数是[] ,但是函数似乎每次都“记住了”上次添加了'end' 后的list。原因解释如下:
Python函数在定义的时候,默认参数list的值就被计算出来了,即[] ,因为默认参数list也是⼀个变量,它指向对象[] ,每次调⽤该函数,如果改变了list的内容,则下次调⽤时,默认参数的内容就变了,不再是函数定义时的[]了。
定义默认参数要牢记⼀点:默认参数必须指向不变对象!
因此定义默认参数时⼀定要使⽤不可变对象(int、float、str、tuple)。使⽤可变对象语法上没错,但在逻辑上是不安全的,代码量⾮常⼤时,容易产⽣很难查的bug。
要修改上⾯的例⼦,我们可以⽤None 这个不变对象来实现:
def add_end(list=None):
if list == None:
list = []
list.append('end')
return list
print(add_end([1,2,3]))
print(add_end(['x','y']))
print(add_end())
print(add_end())
print(add_end())
输出:
[1, 2, 3, 'end']
['x', 'y', 'end']
['end']
['end']
['end']
现在,⽆论调⽤多少次,都不会有问题。
为什么要设计str 、 None 这样的不变对象呢?因为不变对象⼀旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读⼀点问题都没有。我们在编写程序时,如果可以设计⼀个不变对象,那就尽量设计成不变对象。
三、可变参数
在Python函数中,还可以定义可变参数。顾名思义,可变参数就是传⼊的参数个数是可变的,可以是1个、2个到任意个,还可以是0个。
我们以数学题为例⼦,给定⼀组数字a,b,c…… ,请计算a^2 + b^2 + c^2 +...
要定义出这个函数,我们必须确定输⼊的参数。由于参数个数不确定,我们⾸先想到可以把a,b,c……作为⼀个list或tuple 传进来,这样,函数可以定义如下:
def calculator(numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calculator([2,3]))
print(calculator((3,5,6)))
输出:
13
70
但是调⽤的时候,需要先组装出⼀个list 或tuple,如果利⽤可变参数,调⽤函数的⽅式就可以简化:
def calculator(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
print(calculator(2,3))
print(calculator(3,5,6))
输出:
13
70
定义可变参数和定义⼀个list 或tuple 参数相⽐,仅仅在参数前⾯加了⼀个* 号。在函数内部,参数numbers接收到的是⼀个tuple(可变参数将以tuple形式传递),因此,函数代码完全不变。但是,调⽤该函数时,可以传⼊任意个参数,包括0个参数。
如果已经有⼀个list或者tuple,要调⽤⼀个可变参数怎么办?可以这样做:
nums = [2,3,4]
print(calculator(nums[0],nums[1],nums[2]))
输出:
29
这种写法当然是可⾏的,问题是太繁琐,所以Python允许你* 在list或tuple前⾯加⼀个号**,把list或tuple的元素变成可变参数传进去:
nums = [2,3,4]
print(calculator(*nums))
输出:
29
nums 表⽰把nums 这个list的所有元素作为可变参数传进去。这种写法相当有⽤,⽽且很常见。
四、关键字参数
python的可变参数以tuple形式传递,⽽关键字参数则是以dict形式传递。
即可变参数传递的是参数值,关键字参数传递的是参数名:参数值键值对。
形式: **kw 这是惯⽤写法,建议使⽤,容易被理解
def stu_info(name,gender,**kw):
print('name is:',name,' gender is:',gender,' other is :',kw)
stu_info('Bob','M',age=7,city='TJ')
stu_info('Lucy','F',city='BJ')
输出:
name is: Bob gender is: M other is : {'age': 7, 'city': 'TJ'}
name is: Lucy gender is: F other is : {'city': 'BJ'}
可变参数和关键字参数都可以接受0个或者多个参数
五、命名关键字参数
Python的命名关键字参数对传⼊的关键字参数做了进⼀步的限制。
格式:在关键字参数前增加⼀个”*”。
def stu_info(name,gender,*,age,city):
print('name is:',name,' gender is:',gender,' age:',age,' city:',city)
stu_info('Bob','M',age=7,city='TJ')
stu_info('Lucy','F',city='BJ',age=10)
输出:
name is: Bob gender is: M age: 7 city: TJ
name is: Lucy gender is: F age: 10 city: BJ
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论