三、Python基础之函数
函数
为实现代码的重复利用,对实现某一功能的代码进行封装以实现代码抽象,方便重复调用
python常用内置函数在builtins.py中
print() # 输出
type() # 返回类型
id() # 返回内存地址
input() # 输入
len() # 返回长度
open() # 打开文件
round() #返回浮点数x的四舍五入值
abs() # 取绝对值
函数调用
在Python中调用一个函数,需要知道这个函数的名称和传入参数
a1 = abs(-1)
print(a1) # 1
a2 = abs(-1,-2)
print(a2) # TypeError: abs() takes exactly one argument (2 given)
a3 = abs('a')
print(a3) # TypeError: bad operand type for abs(): 'str'
'''
函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
'''
a4 = abs # 变量a4指向abs函数
print(a4) # <built-in function abs>
print(a4(-1)) # 1
调用函数的时候,如果传入的参数数量不对,会报TypeError的错误,并且Python会明确地告诉你:abs()有且仅有1个参数,但给出了两个;
如果传入的参数数量是对的,但参数类型不能被函数所接受,也会报TypeError的错误,并且给出错误信息:str是错误的参数类型;
自定义一个函数
Python中定义一个函数,使用 def 语句,def+函数名+(参数)+: ,通过语句块缩进来编写函数体,通过 return 来返回值
def add(x,y):
sum = x + y
return sum
a = add(2,3)
print(a) # 5
def add(x,y):
sum = x + y
a = add(2,3)
print(a) # None
注:函数需要return来把数据返回给外部调用,如果不写return,函数默认return None
函数在内部执行语句时,一旦执行到return,函数就执行完毕并把结果返回,即使return下面有同样缩进的语句块,但并不会执行
def add(x,y):
sum = x + y
return sum
print("这是函数中return后的语句") # 在调用函数时,该print语句并不会被执行
空函数
有确定的 def+函数名+(参数)+: ,在函数体中用 pass 代替实际的代码语句
def func():
pass # pass语句什么都不做,实际上 pass 通常作为代码的点位符,在程序框架设计中常用
返回多个值
函数通过 return 返回单个值,同样也可返回多个值
def names(x,y):
name_1 = x
name_2 = y
return name_1, name_2
n = names('Jack','Flack')
print(n) # 返回('Jack', 'Flack')
print(type(n)) # 返回类型 <class 'tuple'>
Python中函数return多个值时,返回类型为 tuple(元祖),tuple中包含多个值
任务:
定义一个函数,传入参数为一个list, l1 = [1,2,3,4,5,6......n],对这个list 按 12+22+32.+....+n2 累加,返回这个累加值。
def sum(n):
sum = 0
for each in range(1,n+1):
sum = sum+each*each
return sum
if __name__ == '__main__':
total = sum(100)
print(total)
函数的参数
Python函数的定义比较灵活,除正常定义必选参数外,还可以使用默认参数、可变参数和关键字参数,在处理复杂参数的同时,方便简化调用
'''定义一个函数,实现x2+1的计算'''
def formula(x):
return x*x+1
对于函数 formula(x) ,参数 x 就是一个位置参数,当我们调用 func函数时,就必须传入并且只传入一个参数 x
a1 = formula(3) # 参数传入3,等同于x=3
print(a1) # 10
a2 = formula(x=4)
print(a2) # 17
现在如果要通过函数来实现 x2+ y,在formula的参数中就需要传入x, y两个参数
'''定义一个函数,实现x2+y的计算'''
def formula(x,y):
return x*x+y
a3 = formula(3,2) # 调用formula函数时,传入的参数为3和2,按照位置相当于x=3,y=2,结果为11
a4 = formula(2,3) # 调用formula函数时,传入的参数为2和3,按照位置相当于x=2,y=3,结果为7
传参时按照参数位置填入对应参数,就属于位置参数
默认参数
根据 formula函数,如果实际工作中,这个函数更多的是用来计算 x2+1,但我们也需要这个函数能计算 x2+y,为了简化代码调用,可以给 y 指定一个默认参数 y=1
def formula(x,y=1):
return x*x+y
a5 = formula(3) # 调用formula函数时,虽然只传入的参数x=3,但定义函数时默认y=1,等价于formula(3,1)所以结果为10
从上面例子可以看到,默认参数可以简化函数的调用
需要注意:定义函数时,必选参数放前,默认参数放后
def formula(x=3,y): # SyntaxError: non-default argument follows default argument
return x*x+y
解释器会报错:SyntaxError: non-default argument follows default argument
可变参数
例:当我们需要定义一个函数,实现a2+b2+c2+d2.......+n2,n为任意数
def formula(*numbers): # *numbers为可变参数(numbers类型为元祖,用于接收任意个传入的参数),即调用该formula函数时,可传入任意数量参数
sum = 0
print(type(numbers),numbers) # <class 'tuple'> numbers类型为元祖
for i in numbers:
sum += i*i
return sum
a6 = formula(1) # 此时可变参数numbers接收的参数是1,numbers = (1,),结果为1
a7 = formula(1,2,3) # 此时可变参数numbers接收的参数是1,2,3,numbers=(1,2,3),结果为14
如果需要传入的参数是一个list或tuple,可通过*+参数来对list或tuple解包
n = [1,2,3,4]
a8 = formula(*n) # *n作用是把n中的元素全部取出,放入numbers元祖中,等价于formula(1,2,3,4)
通过 *n 把 n这个list中所有元素解包后作为可变参数传入函数,是一种常用方法
关键字参数
关键字参数允许传入0个或任意个带参数名的参数,这些关键字参数在函数内部以字典的形式存储
'''定义一个函数,存储学生信息'''
def student_info(name, age, **kw):
student_name = name
student_age = age
key_values = kw # **kw是以字典类型来存储传入的关键字参数
print("key_values类型:",type(key_values))
print(student_name, student_age, key_values)
a9 = student_info('Jie',18) # key_values类型: <class 'dict'>
Jie 18 {}
a10 = student_info('Jie',18,city='Shanghai',country='China')
# key_values类型: <class 'dict'>
# Jie 18 {'city': 'Shanghai', 'country': 'China'}
把一个已声明的字典作为关键字参数传入 student_info函数,可通过 **+变量名 实现
more_info = {'city': 'Shanghai', 'country': 'China'}
a11 = student_info('Jie',18,\*\*more_info)
**more_info作用是把字典more_info中的key:value解包后作为关键字参数以字典形式存入kw中
注意:**more_info 只是对more_info拷贝,因此在函数内更改这个more_info是不会对原来的more_info产生影响的
参数组合
在Python中定义函数时,可以用必选参数、默认参数、可变参数、关键字参数,组合使用
参数定义的顺序,位置参数-可变参数-默认参数-可变关键字参数
def func_1(a,b,*args,c=3,**kw):
print(f"参数a={a},参数b={b},可变参数args={args},参数c={c},关键字参数kw={kw}")
a12 = func_1(1,2) # 参数a=1,参数b=2,参数c=3,可变参数args=(),关键字参数kw={}
a13 = func_1(1,2,4,'A','B',k='D',v='E')
# 参数a=1,参数b=2,参数c=4,可变参数args=('A','B'),关键字参数kw={'k': 'D', 'v': 'E'}
小结:
1、Python函数定义中参数形态比较灵活,可以传入复杂的参数,又方便简单调用;
2、默认参数不能是可变对象(List),可变对象引发程序逻辑错误;
3、可变参数 *args,接收一个tuple;
4、可变关键字参数 **kw, 接收一个dict;
5、可变参数可直接传入:func(1,2,3),又可以通过list或tuple,再通过*解包的方式传入:func(*(1,2,3));
6、关键字参数可直接传入:func(x=1,y=2),又可以通过dict,经过**解包方式传入:func(**{'k'=1,'v'=1};
7、参数组合时,参数定义顺序:位置参数-可变参数-默认参数-可变关键字参数(同学们注意下基于python参数特性,文档此处有修改)