第九章:函数
9.1 什么是函数?
函数就像一个可以重复使用的工具包,你把原材料放进去,它就能按照预定的方式加工并返回结果。使用函数可以避免重复编写相同的代码,让程序更加模块化和易于维护。
# 简单的函数示例defgreet(name):"""向指定的人问好"""returnf"你好,{name}!"# 使用函数message=greet("张三")print(message)# 你好,张三!9.2 函数的定义和调用
9.2.1 定义函数
使用def关键字定义函数:
语法格式:
def函数名(参数1,参数2,...):"""函数文档字符串(可选)"""# 函数体代码return返回值# 可选# 示例:计算两个数的和defadd(a,b):"""计算两个数的和"""result=a+breturnresult9.2.2 调用函数
定义函数后,可以通过函数名和参数来调用它:
# 调用add函数sum_result=add(3,5)print(sum_result)# 8# 直接使用返回值print(add(10,20))# 309.3 函数的参数
9.3.1 位置参数
位置参数是按照定义时的顺序传递的参数:
defintroduce(name,age,city):"""自我介绍函数"""returnf"我叫{name},今年{age}岁,来自{city}"# 必须按照顺序传递参数result=introduce("张三",25,"北京")print(result)# 我叫张三,今年25岁,来自北京9.3.2 关键字参数
关键字参数通过参数名来指定值,可以不按顺序:
# 使用关键字参数,顺序不重要result=introduce(age=25,city="上海",name="李四")print(result)# 我叫李四,今年25岁,来自上海# 混合使用位置参数和关键字参数result=introduce("王五",city="广州",age=30)print(result)# 我叫王五,今年30岁,来自广州9.3.3 默认参数
可以为参数指定默认值,调用时可以不传递这些参数:
defgreet(name,greeting="你好"):"""问候函数,带有默认参数"""returnf"{greeting},{name}!"# 使用默认参数print(greet("张三"))# 你好,张三!# 覆盖默认参数print(greet("李四","Hello"))# Hello,李四!9.3.4 可变参数(⚠️本人很少用)
9.3.4.1 *args - 可变位置参数
接收任意数量的位置参数:
defsum_numbers(*args):"""计算任意数量数字的和"""total=0fornuminargs:total+=numreturntotalprint(sum_numbers(1,2,3))# 6print(sum_numbers(1,2,3,4,5))# 159.3.4.2 **kwargs - 可变关键字参数
接收任意数量的关键字参数:
defcreate_student(**kwargs):"""创建学生信息"""student={}forkey,valueinkwargs.items():student[key]=valuereturnstudent# 使用可变关键字参数student1=create_student(name="张三",age=20,major="计算机")student2=create_student(name="李四",age=22,city="北京",score=95)print(student1)# {'name': '张三', 'age': 20, 'major': '计算机'}print(student2)# {'name': '李四', 'age': 22, 'city': '北京', 'score': 95}9.3.5 参数组合
各种参数类型可以组合使用,但必须按特定顺序:
defcomplex_function(a,b,c=10,*args,**kwargs):"""复杂的参数组合"""print(f"a={a}, b={b}, c={c}")print(f"args:{args}")print(f"kwargs:{kwargs}")complex_function(1,2,3,4,5,name="张三",age=20)# 输出:# a=1, b=2, c=3# args: (4, 5)# kwargs: {'name': '张三', 'age': 20}9.4 返回值
9.4.1 返回单个值
defsquare(x):"""计算平方"""returnx*x result=square(5)print(result)# 259.4.2 返回多个值
Python函数可以返回多个值,实际上返回的是一个元组:
defcalculate(a,b):"""计算和、差、积、商"""sum_result=a+b difference=a-b product=a*b quotient=a/bifb!=0else"除数不能为0"returnsum_result,difference,product,quotient# 接收多个返回值s,d,p,q=calculate(10,2)print(f"和:{s}, 差:{d}, 积:{p}, 商:{q}")9.4.3 无返回值
如果函数没有return语句或return后面没有值,则返回None:
defprint_hello(name):"""打印问候语,没有返回值"""print(f"Hello,{name}!")result=print_hello("张三")# Hello, 张三!print(result)# None9.5 变量的作用域
9.5.1 局部变量和全局变量
# 全局变量global_var="我是全局变量"deftest_function():# 局部变量local_var="我是局部变量"print(local_var)# 可以访问局部变量print(global_var)# 可以访问全局变量test_function()# print(local_var) # 错误!不能访问局部变量9.5.2 global关键字
在函数内部修改全局变量需要使用global关键字:
count=0defincrement():globalcount# 声明使用全局变量count+=1print(f"初始值:{count}")# 0increment()print(f"调用后:{count}")# 19.5.3 nonlocal关键字(⚠️本人没用过)
在嵌套函数中修改外部函数的变量需要使用nonlocal:
defouter():x=10definner():nonlocalx# 声明使用外部函数的变量x=20print(f"内部函数:{x}")inner()print(f"外部函数:{x}")outer()# 输出:# 内部函数:20# 外部函数:209.6 函数的类型
9.6.1 内置函数
Python提供的内置函数len()、max()、min()、sum()、sorted()…:
# 常见内置函数numbers=[1,2,3,4,5]print(len(numbers))# 5print(max(numbers))# 5print(min(numbers))# 1print(sum(numbers))# 15print(sorted(numbers))# [1, 2, 3, 4, 5]9.6.2 用户自定义函数
我们自己编写的函数:
defis_even(number):"""判断数字是否为偶数"""returnnumber%2==0print(is_even(4))# Trueprint(is_even(5))# False9.6.3 匿名函数(lambda)⚠️了解即可
使用lambda关键字创建小型匿名函数:
语法:lambda 参数: 表达式
# 简单的lambda函数square=lambdax:x*xprint(square(5))# 25# 直接在需要函数的地方使用numbers=[1,2,3,4,5]even_numbers=list(filter(lambdax:x%2==0,numbers))print(even_numbers)# [2, 4]# 使用lambda排序students=[("张三",85),("李四",92),("王五",78)]students_sorted=sorted(students,key=lambdax:x[1],reverse=True)print(students_sorted)# [('李四', 92), ('张三', 85), ('王五', 78)]9.7 函数的高级特性(⚠️了解即可)
9.7.1 函数作为参数
函数可以作为参数传递给其他函数:
defapply_operation(numbers,operation):"""对数字列表应用操作"""results=[]fornuminnumbers:results.append(operation(num))returnresults# 定义操作函数defsquare(x):returnx*xdefdouble(x):returnx*2# 使用函数作为参数numbers=[1,2,3,4,5]squares=apply_operation(numbers,square)doubles=apply_operation(numbers,double)print(squares)# [1, 4, 9, 16, 25]print(doubles)# [2, 4, 6, 8, 10]9.7.2 函数作为返回值
函数可以返回另一个函数:
defcreate_multiplier(factor):"""创建乘法器函数"""defmultiplier(x):returnx*factorreturnmultiplier# 创建特定的乘法器double=create_multiplier(2)triple=create_multiplier(3)print(double(5))# 10print(triple(5))# 159.7.3 装饰器
装饰器是一种修改函数行为的高级技术:
deftimer(func):"""计时装饰器"""defwrapper(*args,**kwargs):importtime start_time=time.time()result=func(*args,**kwargs)end_time=time.time()print(f"函数{func.__name__}运行时间:{end_time-start_time:.6f}秒")returnresultreturnwrapper# 使用装饰器@timerdefslow_function():"""模拟耗时操作"""importtime time.sleep(1)return"完成"result=slow_function()# 输出:函数 slow_function 运行时间:1.000123秒9.8 递归函数(⚠️了解即可)
函数调用自身称为递归:
deffactorial(n):"""计算阶乘(递归实现)"""ifn==0orn==1:return1else:returnn*factorial(n-1)print(factorial(5))# 120deffibonacci(n):"""计算斐波那契数列(递归实现)"""ifn<=1:returnnelse:returnfibonacci(n-1)+fibonacci(n-2)# 打印前10个斐波那契数foriinrange(10):print(fibonacci(i),end=" ")# 0 1 1 2 3 5 8 13 21 349.9 文档字符串
为函数添加文档说明:
defcalculate_bmi(weight,height):""" 计算身体质量指数(BMI) 参数: weight -- 体重,单位:千克 height -- 身高,单位:米 返回: BMI值,保留两位小数 """bmi=weight/(height**2)returnround(bmi,2)# 查看文档字符串print(calculate_bmi.__doc__)# 使用help函数查看help(calculate_bmi)本章笔记:
- 函数是可重用的代码块,提高代码的模块化和可维护性。
- 使用def关键字定义函数,通过函数名和参数调用函数。
- 函数参数有多种类型:位置参数、关键字参数、默认参数、可变参数。
- 函数可以返回单个值或多个值,没有return语句时返回None。
- 变量作用域分为全局作用域和局部作用域,使用global和nonlocal修改变量作用域。
- 函数类型包括内置函数、用户自定义函数和匿名函数(lambda)。
- 函数可以作为参数传递,也可以作为返回值,支持装饰器等高级特性。
- 递归函数调用自身解决特定类型的问题。
- 文档字符串为函数提供说明文档。
- 函数中可以使用异常处理来提高健壮性。