在编程中,经常会遇到 “重复编写相同或相似代码” 的场景(比如多次计算列表求和、判断数据合法性)。函数(Function)就是为解决这一问题而生的 —— 它将一段实现特定功能的代码块 “封装” 起来,通过一个名字调用,实现代码的复用性与可维护性。今天就全面讲解 Python 函数的核心用法,从基础定义到实战封装,让你轻松用函数优化代码结构!
函数的使用分为两步:定义函数(封装代码块)和调用函数(使用封装好的功能)。Python 用def关键字定义函数,语法简洁清晰。
语法结构:
def 函数名(参数列表):
  """函数的文档字符串(可选,用于说明功能)"""
  # 函数体:实现功能的代码块
  代码语句
  # 返回值(可选,用return语句返回结果)
  return 返回值
函数名:遵循 Python 命名规范(小写字母、下划线分隔,如calculate_sum),见名知意;
参数列表:函数接收的 “输入数据”,可选(无参数时括号留空);
文档字符串(docstring):用三重引号包裹,说明函数功能、参数、返回值等,增强可读性;
函数体:实现函数核心功能的代码,需缩进(通常 4 个空格);
return 语句:函数的 “输出结果”,可选(无 return 时默认返回None)。
def calculate\_sum(a, b):
  """计算两个数的和
   
  参数:
  a: 第一个数字(int/float)
  b: 第二个数字(int/float)
   
  返回:
  int/float: 两个数的和
  """
  result = a + b # 函数体:计算和
  return result # 返回结果
定义函数后,需要通过 “函数名 + 括号” 调用,才能执行函数体中的代码并获取结果。
语法结构:
函数名(参数值列表) # 传入参数值,调用函数
calculate_sum函数\# 1. 调用函数,传入参数值,获取返回结果
sum\_result = calculate\_sum(3, 5)
print("3 + 5 =", sum\_result) # 输出:3 + 5 = 8
\# 2. 直接调用函数,不接收返回结果(仅执行函数体)
calculate\_sum(10, 20) # 函数会执行,但结果不会被保存
\# 3. 函数返回值可直接作为其他操作的参数
print("100 + 200 =", calculate\_sum(100, 200)) # 输出:100 + 200 = 300
调用函数时,传入的 “参数值数量” 和 “类型” 需与函数定义的 “参数列表” 匹配,否则可能报错(如calculate_sum(3)会因缺少参数报错,calculate_sum("a", 5)会因类型不匹配报错)。
函数的参数和返回值都是可选的,可根据功能需求灵活设计。比如定义一个 “打印欢迎信息” 的函数,无需输入参数,也无需返回结果:
def print\_welcome():
  """打印欢迎信息(无参数、无返回值)"""
  print("=" \* 20)
  print("欢迎使用Python函数演示系统")
  print("=" \* 20)
\# 调用函数
print\_welcome()
运行结果:
\====================
欢迎使用Python函数演示系统
\====================
参数是函数与外部交互的 “接口”,Python 支持多种参数类型,能满足不同场景下的输入需求。按使用方式可分为:位置参数、关键字参数、默认参数、可变参数等。
位置参数是最常用的参数类型,调用时需按函数定义的 “参数顺序” 传入对应的值,数量必须一致。
def calculate\_rect\_area(length, width):
  """计算长方形面积(位置参数示例)
   
  参数:
  length: 长方形的长(int/float)
  width: 长方形的宽(int/float)
   
  返回:
  int/float: 长方形的面积
  """
  area = length \* width
  return area
\# 调用函数:按顺序传入长和宽(位置参数必须按顺序)
area1 = calculate\_rect\_area(5, 3) # length=5,width=3
area2 = calculate\_rect\_area(3, 5) # length=3,width=5
print("长方形1面积:", area1) # 输出:15
print("长方形2面积:", area2) # 输出:15(长和宽交换,面积不变)
如果位置参数顺序错误,可能导致逻辑错误(比如计算 “长方形周长” 时,参数顺序错误不影响结果,但计算 “时间差” 时顺序错误会导致结果为负)。
关键字参数通过 “参数名 = 值” 的形式传入,无需按顺序,能明确每个值对应的参数,增强代码可读性,尤其适合参数较多的场景。
calculate_rect_area函数\# 1. 纯关键字参数调用(顺序可任意)
area1 = calculate\_rect\_area(length=5, width=3)
area2 = calculate\_rect\_area(width=3, length=5) # 顺序交换,结果一致
print("面积1:", area1) # 输出:15
print("面积2:", area2) # 输出:15
\# 2. 位置参数与关键字参数混合调用(位置参数必须在关键字参数之前)
area3 = calculate\_rect\_area(5, width=3) # 正确:位置参数在前
\# area4 = calculate\_rect\_area(length=5, 3) # 错误:关键字参数不能在位置参数之前
混合调用时,位置参数必须在关键字参数左侧;
一个参数不能同时用位置和关键字传递(如calculate_rect_area(5, length=3)会报错,length被重复赋值)。
默认参数在函数定义时指定 “默认值”,调用时若未传入该参数,则使用默认值;若传入,则覆盖默认值。默认参数适合 “大多数情况下使用固定值,少数情况需要自定义” 的场景。
def 函数名(参数1, 参数2=默认值, 参数3=默认值, ...):
  函数体
def calculate\_total\_price(price, quantity, discount=1.0):
  """计算商品总价(默认参数示例)
   
  参数:
  price: 商品单价(int/float)
  quantity: 购买数量(int)
  discount: 折扣率(int/float,默认1.0,即无折扣)
   
  返回:
  int/float: 商品总价(单价 \* 数量 \* 折扣率)
  """
  total = price \* quantity \* discount
  return total
\# 1. 未传入折扣,使用默认值1.0
total1 = calculate\_total\_price(100, 5) # 单价100,数量5,折扣1.0
print("总价1(无折扣):", total1) # 输出:500.0
\# 2. 传入折扣,覆盖默认值
total2 = calculate\_total\_price(100, 5, 0.8) # 折扣0.8(8折)
total3 = calculate\_total\_price(100, 5, discount=0.7) # 关键字参数传折扣
print("总价2(8折):", total2) # 输出:400.0
print("总价3(7折):", total3) # 输出:350.0
默认参数必须放在位置参数右侧(如def func(a=1, b)会报错,默认参数不能在普通位置参数之前);
默认参数的默认值应设为不可变类型(如 int、str、tuple),避免使用 list、dict 等可变类型(否则默认值可能被多次调用修改,导致意外结果)。
当函数需要接收的参数数量不确定时(比如计算任意多个数的和),可以用可变参数:*args(接收任意多个位置参数,打包成元组)和**kwargs(接收任意多个关键字参数,打包成字典)。
*args:接收任意多个位置参数*args中的*表示 “可变参数”,args是约定俗成的参数名(可自定义,但推荐用args),函数内部args是一个元组,包含所有传入的位置参数。
def calculate\_sum(\*args):
  """计算任意多个数的和(\*args示例)
   
  参数:
  \*args: 任意多个位置参数(int/float)
   
  返回:
  int/float: 所有参数的和
  """
  total = 0
  for num in args: # args是元组,可遍历
  total += num
  return total
\# 调用函数:传入任意数量的位置参数
sum1 = calculate\_sum(1, 2, 3) # args = (1, 2, 3)
sum2 = calculate\_sum(10, 20, 30, 40) # args = (10, 20, 30, 40)
sum3 = calculate\_sum() # args = (),返回0
print("sum1:", sum1) # 输出:6
print("sum2:", sum2) # 输出:100
print("sum3:", sum3) # 输出:0
**kwargs:接收任意多个关键字参数**kwargs中的**表示 “关键字可变参数”,kwargs是约定俗成的参数名(可自定义,推荐用kwargs),函数内部kwargs是一个字典,包含所有传入的 “参数名 = 值” 对。
def print\_user\_info(\*\*kwargs):
  """打印用户信息(\*\*kwargs示例)
   
  参数:
  \*\*kwargs: 任意多个关键字参数(如name、age、city等)
   
  返回:
  None
  """
  print("用户信息:")
  for key, value in kwargs.items(): # kwargs是字典,可遍历键值对
  print(f"{key}: {value}")
\# 调用函数:传入任意数量的关键字参数
print\_user\_info(name="小明", age=20, city="北京") # kwargs = {"name":"小明", "age":20, "city":"北京"}
print\_user\_info(name="小红", gender="女") # kwargs = {"name":"小红", "gender":"女"}
运行结果(第一次调用):
用户信息:
name: 小明
age: 20
city: 北京
*args与**kwargs混合使用*args和**kwargs可同时用于一个函数,此时*args必须在**kwargs左侧,能同时接收任意数量的位置参数和关键字参数。
def mixed\_args(\*args, \*\*kwargs):
  """混合使用\*args和\*\*kwargs"""
  print("位置参数(args):", args)
  print("关键字参数(kwargs):", kwargs)
\# 调用函数
mixed\_args(1, 2, 3, name="小明", age=20)
运行结果:
位置参数(args): (1, 2, 3)
关键字参数(kwargs): {'name': '小明', 'age': 20}
当已有一个列表(或元组)、字典,想将其元素作为函数的参数传入时,可以用参数解包:
列表 / 元组用*解包,拆分为位置参数;
字典用**解包,拆分为关键字参数。
*)作为位置参数def calculate\_rect\_area(length, width):
  """计算长方形面积"""
  return length \* width
\# 已有一个列表,存储长和宽
rect\_dimensions = \[5, 3] # 对应length=5,width=3
\# 解包列表,作为位置参数传入
area = calculate\_rect\_area(\*rect\_dimensions) # 等价于 calculate\_rect\_area(5, 3)
print("长方形面积:", area) # 输出:15
**)作为关键字参数def print\_user\_info(name, age):
  """打印用户信息"""
  print(f"姓名:{name},年龄:{age}")
\# 已有一个字典,存储用户信息
user\_info = {"name": "小明", "age": 20} # 对应name="小明",age=20
\# 解包字典,作为关键字参数传入
print\_user\_info(\*\*user\_info) # 等价于 print\_user\_info(name="小明", age=20)
运行结果:
姓名:小明,年龄:20
函数的返回值用return语句定义,是函数对外部的 “输出”。return有两个核心作用:返回结果和终止函数(return后的代码不会执行)。
一个函数可以返回任意类型的数据(int、str、list、dict 等),也可以返回另一个函数的调用结果。
def find\_max(numbers):
  """找到列表中的最大值
   
  参数:
  numbers: 包含数字的列表(list)
   
  返回:
  int/float: 列表中的最大值;若列表为空,返回None
  """
  if not numbers: # 判断列表是否为空
  return None # 空列表返回None
  max\_num = numbers\[0]
  for num in numbers\[1:]:
  if num > max\_num:
  max\_num = num
  return max\_num # 返回最大值
\# 调用函数
max1 = find\_max(\[1, 3, 5, 2])
max2 = find\_max(\[]) # 空列表
print("最大值1:", max1) # 输出:5
print("最大值2:", max2) # 输出:None
Python 支持一个函数返回多个值,用逗号分隔多个返回值,函数会自动将其打包成一个元组;调用时可通过 “多变量赋值” 拆包接收。
def find\_max\_min(numbers):
  """找到列表中的最大值和最小值
   
  参数:
  numbers: 包含数字的列表(list)
   
  返回:
  tuple: (最大值, 最小值);若列表为空,返回(None, None)
  """
  if not numbers:
  return None, None
  max\_num = min\_num = numbers\[0]
  for num in numbers\[1:]:
  if num > max\_num:
  max\_num = num
  if num < min\_num:
  min\_num = num
  return max\_num, min\_num # 多个返回值,自动打包成元组
\# 调用函数:多变量赋值拆包
max\_val, min\_val = find\_max\_min(\[1, 3, 5, 2, 0])
print("最大值:", max\_val) # 输出:5
print("最小值:", min\_val) # 输出:0
\# 也可以用单个变量接收(得到元组)
result = find\_max\_min(\[10, 20, 5])
print("结果(元组):", result) # 输出:(20, \</doubaocanvas>
(注:文档部分内容可能由 AI 生成)