参考教程:廖雪峰官网https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000
一、函数的定义
Python中定义一个函数需要使用def语句,依次确定函数名、参数及函数体内容:
#一个求绝对值的函数 def my_abs(x): if x>0: return x else: return -x
如果函数体内没有return语句,也会返回None。return None可以简写为return。
如果要定义一个什么都不做的函数(空函数),可以用pass语句,pass也可以用在if语句中:
def nop(): pass def nopx(n): if n>0: pass else: return
*返回多个值的函数
#给出长方形的长和宽,输出面积和周长 def sqcount(l,w): area=l*w length=2*(l+w) return area,length
可以增加一些语句看看这个返回的到底是什么:
x,y=sqcount(3,4) print(x,y) #这里输出12,14 r=sqcount(5,6) print(r) #这里输出(30,22)
从上述代码可以看出,虽然看起来函数返回了多个值,其实本质还是返回了一个值,只是这个值的类型是元组!
二、函数的参数
(一)位置参数
前面定义的my_abs()以及sqcount()中的参数都是位置参数,它是调用函数时必须传入的参数,并且按照定义时的位置顺序传递给对应参数。
(二)默认参数
有一些情况,参数中有部分参数在多数情况下都是某一个值,这时候可以在定义函数的时候将其固定设置下来,在调用时候如果该参数值和定义时对应的参数值相同则可以不写出,在不相同时候则需要写出具体值代入函数。
#默认情况下,国籍设置为china def person_info(name,age,country='china'): print('name=',name,'age=',age,'country=',country) return True #ZhangHua国籍为china则可以不传入国籍参数 person_info('ZhangHua',26) #Tom国籍为美国,则需要设置 person_info('Tom',29,'America')
需要注意的是,当有多个默认参数时,在调用的时候可以按照顺序提供默认参数,也可以加上参数名以指定默认参数之间的对应关系。
def enroll(name, gender, age=6, city='Beijing'): print('name:', name) print('gender:', gender) print('age:', age) print('city:', city) #年龄信息参数的传入是按照定义时候的第三的顺序 #所以可以不加参数名 enroll('Bob', 'M', 7) #这里年龄使用了定义时的默认值,所以不写出 #但需要设置城市,而位置关系又和定义时候不一致 #所以需要写上'city=' enroll('Adam', 'M', city='Tianjin')
关于默认参数还必须注意一点,如:
#定义时候使用了默认参数L,指向一个空列表 def testa(L=[]): L.append('END') return L print(testa()) #输出['END'] print(testa()) #输出['END',‘END']
两次同样的调用,为什么输出不一样呢?在定义的时候默认参数L的值就被计算了,即指向[],L也是一个变量,在每次调用时如果改变了L的内容(指向),默认参数自然就随之而变了。所以:默认参数必须指向不可变对象!
可以通过None修改上面的代码:
def testa(L=None): if L is None: L=[] L.append('END') return L
(三)可变参数
可变参数是指传入的参数数量是可以变化的,任意个的。设计这种参数的情况就是在函数定义的时候不知道调用时会有多少个参数,比如:列表、元组等等。那么就可以将参数整体设置为一个列表或者元组等等,而Python对于变量是不需要指定类型的,所以简单的做法如下:
def calc(numbers): sum=0 for i in numbers: sum=sum+i return sum
但上述这种定义的方法必须传递类型为可迭代类型的数据,如列表等,如传递其他类型比如数值类型的会报TypeError: 'int' object is not iterable的错误。
#正常运行,输出6 x=[1,2,3] print(calc(x)) #报错:参数非迭代类型 y=2 print(calc(y))
对于上面定义的函数,也可以直接传入值:
print(calc([1,2,3])) print(calc((2,3,5,7,11))
这样在使用的时候其实并不够方便,因为需要先组装成一个列表或元组才可以使用,如果想用如下的方式调用可必须用到可变参数的方法:
cal(1,3,5,7,9,11)
可以在定义时把参数变为可变参数:在参数前面加’*':
def calc(*numbers): sum=0 for i in numbers: sum=sum+i return sum
这样就可以直接通过cal(1,3,5,7,9,11)调用,而如果是一个列表或元组的话,在传参时只需要在列表或元组名前加'*'作为参数也可以方便调用:
print(calc(1,3,5,7,9,11)) x=[1,2,3] print(calc(*x)) y=(2,3,5,7) print(calc(*y))
不管参数在传递前是什么类型,是直接的数值传递还是列表或元组,但传入函数后,函数内部都是将这些可变参数组装成一个元组来操作。
(四)关键字参数
关键字参数允许传入任意个含参数名的参数,这些关键字参数在函数内部自动组装成一个字典(dict):
#前两个参数为位置参数,代表姓名和年龄信息 #第三个参数则定义了可选的关键字参数,可以让调用者提供其他信息 def person(name,age,**kw): print(name,'-',age,'-',kw)
#调用者可以只提供必选的位置参数信息
#输出:LiNa - 32 - {}
person('LiNa',32)
#调用者提供一个信息:国家
#输出: Jenny - 35 - {'country': 'British'}
person('Jenny',35,country='British')
#调用者提供两个信息:国家和性别
#输出:Tom - 39 - {'gender': 'M', 'country': 'Holland'}
person('Tom',39,gender='M',country="Holland")
如果已有一个dict,那可以直接在字典名前加'**',将其作为关键字参数传递:
#输出:LiNa - 32 - {'coutry': 'China', 'gender': 'F', 'food': 'Reganmian'} lina_info={'coutry':'China','gender':'F','food':'Reganmian'} person('LiNa',32,**lina_info)
(五)命名关键字参数
在关键字参数中,调用者可以自行设置传递到关键字参数的参数名,如上述的country,gender和food都是可选并且可自行设置的,如果要限制关键字参数的名字,就需要用到命名关键字参数:
#关键字参数只接受名字为city和job def person(name,age,*,city,job): print(name,'-',age,'-',city,'-',job) #这里将会报错,因为没有传递job参数 person('mengfei',50,city='Nanjing') #正常运行,输出:wanggang - 60 - Beijing - Actor person('wanggang',60,city='Beijing',job='Actor')
命名关键字参数可以有默认值,这样的话在调用时候该参数可以不显式指定:
def person(name,age,*,city='Beijing',job): print(name,'-',age,'-',city,'-',job) #输出:wanggang - 60 - Beijing - Actor person('wanggang',60,job='Actor')
当函数参数列表中有可变参数时,后面跟着的命名关键字参数就不再需要一个特殊符号'*'了:
def person(name, age, *args, city, job): print(name, age, args, city, job)
#a,b为位置参数是必选的 #c是可选的默认参数 #args是可选的可变参数 #kw是可选的关键字参数 def f1(a,b,c=0,*args,**kw): print('a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw) #函数调用时,解释器自动按照参数位置和参数名进行传递 #只有两个位置参数,默认c为0 #输出:a= 1 b= 2 c= 0 args= () kw= {} f1(1,2) #位置参数加自定义的默认参数值 #输出:a= 1 b= 2 c= 3 args= () kw= {} f1(1,2,c=3) #位置参数+默认参数+可变参数 #如果有关键字参数则需要加命名 #输出:a= 1 b= 2 c= 3 args= ('a', 'b') kw= {} f1(1,2,3,'a','b') #输出:a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'x': 99} f1(1,2,3,'a','b',x=99)