前言
对于刚接触Python的新手来说,函数是第一个能让你跳出“逐行写代码”的关键知识点。学会函数,你就能把重复的代码封装起来、让逻辑更清晰,甚至能写出可复用、易维护的代码。这篇博客会用最细致的讲解、最易懂的例子,带你彻底搞懂Python函数的所有基础知识点。
一、为什么需要函数?先解决“为什么学”
在没学函数之前,你可能会这样写代码:
# 计算1-2的和print(1+2)# 计算3-4的和print(3+4)# 计算5-6的和print(5+6)这段代码重复了“求和并打印”的逻辑,一旦要修改逻辑(比如改成求积),就得改3处。
而用函数改写后:
defadd(a,b):"""计算两个数的和并打印"""result=a+bprint(result)# 调用函数,只需传不同参数add(1,2)add(3,4)add(5,6)只需修改函数内部的逻辑,所有调用处都会生效。这就是函数的核心价值:代码复用、逻辑解耦、便于维护。
二、函数的基础:定义与调用
函数的本质是“封装好的代码块”,使用分为两步:先定义,再调用。
1. 函数的定义语法
def函数名(参数列表):函数体(要执行的代码)return返回值(可选)def:定义函数的关键字,必须以这个开头;- 函数名:遵循Python命名规则(小写、下划线分隔,如
get_user_name),见名知意; - 参数列表:括号里的内容,是函数接收的“输入”,可空;
return:函数的“输出”,执行到return会立即结束函数,可选。
2. 最基础的函数:无参数、无返回值
# 定义函数:打印固定问候语defsay_hello():"""打印问候语(无参数、无返回值)"""print("你好,欢迎学习Python函数!")# 调用函数:函数名+括号say_hello()# 输出:你好,欢迎学习Python函数!易错点:定义函数时,函数体的缩进不能少;调用函数时,括号必须加,哪怕没有参数。
3. 带参数的函数:让函数更灵活
参数是函数的“输入”,能让函数处理不同的数据。
(1)位置参数(最基础)
调用时按参数定义的顺序传值,是最常用的参数类型。
# 定义:参数a和b是位置参数defcalculate_sum(a,b):"""计算a和b的和并打印"""total=a+bprint(f"{a}+{b}={total}")# 调用:按顺序传10和20,a=10,b=20calculate_sum(10,20)# 输出:10 + 20 = 30(2)关键字参数(提升可读性)
调用时指定参数名,顺序可以打乱,适合参数较多的场景。
# 定义:参数name(姓名)、age(年龄)defprint_person_info(name,age):"""打印个人信息"""print(f"姓名:{name},年龄:{age}")# 关键字参数调用:指定参数名print_person_info(name="小明",age=18)# 输出:姓名:小明,年龄:18# 顺序打乱也可以print_person_info(age=20,name="小红")# 输出:姓名:小红,年龄:20(3)默认参数(简化调用)
定义函数时给参数指定默认值,调用时可省略该参数,默认参数必须放在位置参数后面。
# 定义:age的默认值为18(默认参数)defprint_person_info(name,age=18):"""打印个人信息,年龄默认18"""print(f"姓名:{name},年龄:{age}")# 调用:省略age,使用默认值18print_person_info("小刚")# 输出:姓名:小刚,年龄:18# 调用:传入age,覆盖默认值print_person_info("小丽",22)# 输出:姓名:小丽,年龄:22重要提醒:默认参数应使用不可变对象(数字、字符串、元组),不要用列表、字典等可变对象!
(4)可变长度参数(处理不确定数量的参数)
当你不知道要传多少个参数时,用*args(接收位置参数)和**kwargs(接收关键字参数)。
*args:打包所有位置参数为一个元组
defsum_many(*args):"""计算任意个数的和"""total=0# args是元组,可遍历fornuminargs:total+=numreturntotal# 传3个参数print(sum_many(1,2,3))# 输出:6# 传5个参数print(sum_many(10,20,30,40,50))# 输出:150# 不传参数也可以print(sum_many())# 输出:0**kwargs:打包所有关键字参数为一个字典
defprint_info(**kwargs):"""打印任意关键字参数"""# kwargs是字典,可遍历键值对forkey,valueinkwargs.items():print(f"{key}:{value}")# 传2个关键字参数print_info(name="张三",gender="男")# 输出:# name:张三# gender:男# 传3个关键字参数print_info(brand="Python",version="3.11",usage="编程")# 输出:# brand:Python# version:3.11# usage:编程4. 函数的返回值:用return输出结果
函数执行后如果需要给调用者返回数据,就用return语句。
(1)基本用法
defmultiply(a,b):"""计算a和b的积,返回结果"""result=a*b# 返回结果returnresult# 调用函数,接收返回值product=multiply(5,6)print(product)# 输出:30# 无return的函数,默认返回Nonedefno_return():print("无返回值")res=no_return()print(res)# 输出:None(2)return的特性
- 执行到return,函数立即结束,后面的代码不会执行:
deftest_return():print("执行第一行")return# 结束函数print("执行第二行")# 不会执行test_return()# 输出:执行第一行- 可以返回多个值(实际是返回元组):
defget_user_info():"""返回姓名、年龄、性别"""name="小明"age=18gender="男"# 返回多个值,用逗号分隔returnname,age,gender# 接收多个返回值name,age,gender=get_user_info()print(f"姓名:{name},年龄:{age},性别:{gender}")# 输出:姓名:小明,年龄:18,性别:男# 也可以用一个变量接收(得到元组)info=get_user_info()print(info)# 输出:('小明', 18, '男')三、函数的作用域:变量在哪里能用?
新手很容易踩的坑:函数内的变量和函数外的变量不是一回事!Python的变量作用域分两种:
1. 局部作用域(函数内部)
函数内部定义的变量,只能在函数内使用,外部无法访问。
deftest_local():# 局部变量:只在函数内有效local_var="我是局部变量"print(local_var)# 输出:我是局部变量test_local()# 外部访问局部变量,报错# print(local_var) # 报错:NameError: name 'local_var' is not defined2. 全局作用域(函数外部)
函数外部定义的变量,整个程序都能访问,但函数内不能直接修改(需要用global声明)。
# 全局变量:整个程序有效global_var="我是全局变量"deftest_global():# 访问全局变量(可以)print(global_var)# 输出:我是全局变量# 直接修改全局变量(不行,会创建局部变量)# global_var = "修改全局变量" # 这行执行后,会创建一个局部的global_var,而非修改全局的# 正确修改全局变量:用global声明globalglobal_var global_var="修改后的全局变量"test_global()print(global_var)# 输出:修改后的全局变量3. 易错点总结
| 场景 | 是否可行 | 注意事项 |
|---|---|---|
| 函数内访问全局变量 | 可以 | 无需声明 |
| 函数内修改全局变量 | 直接改不行 | 需用global声明 |
| 函数外访问局部变量 | 不行 | 局部变量仅函数内有效 |
四、函数的调用:那些容易忽略的细节
1. 函数可以嵌套调用
一个函数可以调用另一个函数,这是代码复用的重要方式。
# 定义:计算平方defsquare(num):returnnum*num# 定义:计算两个数的平方和defsum_of_squares(a,b):# 调用square函数square_a=square(a)square_b=square(b)returnsquare_a+square_b# 调用sum_of_squaresresult=sum_of_squares(3,4)print(result)# 输出:25(3²+4²=9+16=25)2. 函数必须先定义后调用
Python是解释型语言,执行到函数调用时,必须已经定义过该函数。
deftest():print("函数定义完成")test()# 输出:函数定义完成五、新手必避的5个坑
- 参数数量不匹配:调用时传的参数个数和定义的不一致,是最常见的错误;
- 默认参数用了可变对象:比如列表、字典,导致多次调用结果异常;
- 忘记缩进函数体:定义函数时,函数体没有缩进,会报错;
- 修改全局变量未用global:函数内直接修改全局变量,实际创建了局部变量,达不到修改目的;
- return后写代码:return后的代码永远不会执行,属于无效代码。
六、实战练习:用函数解决实际问题
学完基础,用一个小例子巩固:写一个函数,判断一个数是否是质数(只能被1和自身整除的大于1的整数)。
defis_prime(num):# 判断一个数是否是质数# 处理特殊情况:小于等于1的数不是质数ifnum<=1:returnFalse# 处理2:唯一的偶质数ifnum==2:returnTrue# 处理偶数:大于2的偶数不是质数ifnum%2==0:returnFalse# 检查从3到num的平方根之间的奇数foriinrange(3,int(num**0.5)+1,2):ifnum%i==0:returnFalse# 所有情况都不满足,是质数returnTrue# 测试函数print(is_prime(7))# 输出:Trueprint(is_prime(10))# 输出:Falseprint(is_prime(1))# 输出:Falseprint(is_prime(2))# 输出:True七、总结
Python函数的核心就是“封装”和“复用”:
- 定义函数用
def,调用函数用函数名(); - 参数让函数能接收不同输入,返回值让函数能输出结果;
- 掌握位置参数、关键字参数、默认参数、可变参数,能应对绝大多数场景;
- 注意作用域问题,避免变量访问/修改出错。
作为新手,不用急于掌握进阶的lambda、装饰器等内容,先把本文的基础知识点练熟:多写几个函数(比如计算面积、判断奇偶、统计列表元素),多踩几次坑,就能彻底理解函数的用法。函数是Python编程的基础,也是迈向更复杂项目的第一步,打好这个基础,后续学习类、模块都会更轻松。