程序中反复执行的代码可以封装到一个代码块中,在需要使用的时候调用一下函数即可。
Python中的函数很灵活,可以在模块中、类之外定义,其作用域是当前模块;也可以在别的函数中定义,即嵌套函数;还可以在类中定义,即方法。
定义函数
注意:Python作为解释性语言,其函数必须先定义后调用,前面的学习中用到了一些函数,如len()、min()、max()等,这些函数是由Python官方提供的,称为内置函数,不需要我们自己去定义。
自定义函数的语法格式如下:
def 函数名(参数列表):
函数体
return 返回值
定义函数的关键字为def,函数名需要符合标识符命名规则,函数可以没有参数,也可以有多个参数,多个参数列表之间用逗号进行分隔;如果有返回值,就要在函数体最后用return语句进行返回,如果没有,可以用return None或者省略return 语句。
输入下面代码
def calculate_Area(a):
return a*a
x = int(input("请输入正方形的边长:"))
area = calculate_Area(x)
print("正方形的面积为:{0}".format(area))
代码运行结果(假设输入的边长为3)
请输入正方形的边长:3
正方形的面积为:9
代码中没有错误处理机制来捕获并处理用户输入非数字时的情况。
下面代码为改进后的代码
def calculate_Area(a):
return a * a
# 循环直到用户输入有效的边长
while True:
try:
x = int(input("请输入正方形的边长:"))
if x <= 0:
print("边长必须是正数,请重新输入!")
continue
break # 输入有效,退出循环
except ValueError:
print("无效的输入,请输入一个整数!")
area = calculate_Area(x)
print(f"正方形的面积为:{area}") # 使用 f-string 格式化输出
函数参数
Python中的函数参数使用很灵活,传参可以有多种方式
使用关键字参数调用函数
采用关键字参数调用函数,在函数定义时不需要做额外的工作。在调用时可以不使用关键字参数调用,对于使用关键字参数调用时,参数顺序可以与函数定义时的顺序不同。特别需要注意的是:一旦其中一个参数采用了关键字参数形式传递,则其后所有参数都必须采用关键字参数调用。
示例代码如下
def calculate_area(width,height):
area = width*height
print("长和宽分别为{0}、{1},面积为{2}".format(width,height,area))
calculate_area(20,20) #未采用关键字参数函数调用
calculate_area(20,height=20) #采用关键字参数函数调用
calculate_area(width=20,height=19)
calculate_area(height=20,width=19)
# calculate_area(width=20,20) 该代码若执行,会显示SyntaxError: positional argument follows keyword argument错误
代码运行结果
长和宽分别为20、20,面积为400
长和宽分别为20、20,面积为400
长和宽分别为20、19,面积为380
长和宽分别为19、20,面积为380
参数默认值
在定义参数时可以为参数设置一个默认值,调用参数时可以忽略该值。在参数列表中,默认值可以跟在参数类型后面,通过等号提供给参数,在调用时,如果调用者没有传递参数,则使用默认值。
与Java中重载的区别:
在Java语言中采用重载可以实现使用同一个方法调用不同的参数,而Python不支持函数重载,而是使用参数默认值的方式提供类似函数重载的功能。因为参数默认值只需要定义一个函数就够了,而重载需要定义多个函数,这会增加代码量。
示例代码如下
def make_drink(name='可乐'):
print("请给我来一杯{0}".format(name))
make_drink() #不传入参数时调用默认参数
make_drink('橙汁') #传入参数时
代码运行结果
请给我来一杯可乐
请给我来一杯橙汁
单星号(*)可变参数
函数的参数个数可以变化,可以接受不确定数量的参数,这种参数称为可变参数。可变参数有两种:参数前加单星号(*)和双星号(**)形式。
其中单星号可变参数在函数中被组装成一个元组,如果已经有一个元组变量,在传递的时候需要对元组进行拆包。需要注意的是:若单星号可变参数不是最后一个参数时,后面的参数需要采用关键字参数形式传递。
示例代码如下
def calculate_sum(*numbers,multiple=1):
total = 0
for number in numbers:
total += number
total = total * multiple
print(total) #也可以修改代码最后两行为return total * multiple
calculate_sum(20,30,40)
calculate_sum(20,30,40,multiple=3)#若调用multiple参数,必须使用关键字参数
#采用元组或列表作为参数
a = (20,30,40)
calculate_sum(*a)
calculate_sum(30,*a)
# 这里的 a 是一个元组 (20, 30, 40),而 calculate_sum 函数使用的是分散的参数,
# 而不是将整个元组作为一个单独的参数。若尝试将 30(一个整数)和 a(一个元组)作为参数传递给函数时,
# Python 会将它们视为两个独立的参数,但 *numbers 是将这些参数解包为独立的元素。
代码运行结果
90
270
90
120
双星号(**)可变参数
双星号可变参数在函数中被组装成一个字典,需要注意的是双星号可变参数必须在正规参数之后,即若此处参数列表改为(**info,sep=':')时,则会发生错误。
示例代码如下
def show_info(sep=':',**info):
print('-----info-----')
for key, value in info.items():
print('{0} {1} {2}'.format(key,sep,value))
show_info('->',name='Tony',age = 18 ,gender ='man')#注意键不要加引号
show_info(student_name='Tony',student_no = '1000',sep='-')
dict1 = {'name':'Tony','age':18}
show_info(**dict1,gender='man',sep='=')
代码运行结果
-----info-----
name -> Tony
age -> 18
gender -> man
-----info-----
student_name - Tony
student_no - 1000
-----info-----
name = Tony
age = 18
gender = man
函数返回值
主要有三种形式:无返回值、单一返回值和多返回值。
无返回值
示例代码如下
def calculate_sum(*numbers,multiple=1):
if len(numbers) == 0:
return #无返回值
上述代码的意义为若未输入数字,则结果为空
单一返回值
针对上述代码改进如下
示例代码如下
def calculate_sum(*numbers,multiple=1):
if len(numbers) == 0:
return #无返回值
totol = 0
for number in numbers:
totol += number
return totol*multiple #单一返回值
print(calculate_sum(0))
print(calculate_sum(30,20,10,multiple=2))
代码运行结果
0
120
多返回值
有时需要函数返回多个值,简单的方式是使用元组,因为元组作为数据结构可以容纳多个数据,且元组不可变,使用起来比较安全。
示例代码如下
def position(time,speed):
posx = speed[0] * time
posy = speed[1] * time
return (posx,posy)#返回X和Y方向的位移
move = position(60.0,(10,-5))
print("物体的位移:({0},{1})".format(move[0],move[1]))
代码运行结果
物体的位移:(600.0,-300.0)
函数变量作用域
变量在模块中创建,其作用域是整个模块,称为全局变量。变量也可以在函数中创建,此时默认其作用域为整个函数,称为局部变量。Python提供了一个 global 关键字,可将函数的局部变量作用域修改为全局的。
示例代码如下
x = 20 #创建一个全局变量x
y = 20 #创建一个全局变量y
def print_value():
x = 10 #创建局部变量
global y #声明y为全局变量
y = 10 #修改全局变量的值
print('函数中 x = {0}'.format(x))
print_value()
print("全局变量 x = {0} y = {1}".format(x,y))
代码运行结果
函数中 x = 10
全局变量 x = 20 y = 10
生成器
在一个函数中使用 yield 关键字返回生成器对象,生成器对象是一种可迭代对象,可迭代对象通过_ next _ ()方法获得元素;与return不同的是,return一次返回所有元素,而yield语句只返回一个元素数据,函数调用不会结束,只是暂停,直到_ next _ ()方法被调用,程序继续执行yield后面的语句代码。
需要注意的是:生成器对象特别适合用于遍历一些大序列对象,它无须将对象的所有元素都载入内存后才开始进行操作,仅在迭代至某个元素时才会将该元素载入内存。
示例代码如下
def square(num):
for i in range(1,num+1):
yield i*i
for i in square(6): #隐式调用生成器的_ _next_ _ ()方法
print(i,end=' ')
代码运行结果
1 4 9 16 25 36
嵌套函数
即在函数体中定义函数,嵌套函数的作用域在外部函数体内
示范代码如下
def calculate(n1,n2,opr):
multiple = 3
#定义相加函数
def add(a,b):
return (a+b)*multiple
#定义相减函数
def sub(a,b):
return (a-b)*multiple
#条件判断
if opr == '+':
return add(n1,n2)
else:
return sub(n1,n2)
print(calculate(10,20,'+'))
print(calculate(20,10,'-'))
代码执行结果
90
30