小白学 Python
AI 编程指南
© 2026 小白学 Python · 基于 walter201230/Python 教程
课程目录关于本站联系方式隐私政策GitHub

函数

完整讲解 · 5 段教学·配 5 道练习题·预计 30 分钟

本页是本章的通读版,可直接读完全部讲解。想动手写代码、跑判分,去 闯关模式。

教学 01 / 05

第五节:函数

之前我们写的代码都是一行一行往下执行。这一节学函数——

函数就是组织好的、可重复使用的、用来实现单一或相关联功能的代码段。

简单说:把一段逻辑包起来反复用。print 就是 Python 内置的函数,这一节你要学怎么自己定义函数。

教学 02 / 05

一、自定义函数

1、函数的组成

python到闯关页运行这段 →
def 函数名(参数1, 参数2, ...):
    函数体
    return 表达式

自定义函数的规则:

  • 用 def 关键字开头,后接函数名和圆括号 ()
  • 任何参数放在圆括号中间
  • 函数内容冒号 + 缩进起始(跟 if、for 一样)
  • return 表达式 结束函数,并把值返回给调用方
  • 不带表达式的 return 相当于返回 None

例子——定义一个求和函数:

python到闯关页运行这段 →
def add(num1, num2):
    return num1 + num2

# 调用
print(add(5, 6))

输出:

11

2、为什么要用函数?

python到闯关页运行这段 →
# 不用函数:每次都要重复写
print('一点水的成绩:及格' if 75 >= 60 else '一点水的成绩:不及格')
print('两点水的成绩:及格' if 88 >= 60 else '两点水的成绩:不及格')
print('三点水的成绩:及格' if 50 >= 60 else '三点水的成绩:不及格')
python到闯关页运行这段 →
# 用函数:定义一次,反复用
def report(name, score):
    print(f"{name}的成绩:{'及格' if score >= 60 else '不及格'}")

report('一点水', 75)
report('两点水', 88)
report('三点水', 50)

代码量少了,逻辑改一处全局生效。函数让代码可以「攒」起来重复用。

练习 1 / 5定义一个 add 函数

请定义一个函数 add(a, b),返回 a + b。

然后调用 add(3, 5) 把结果赋给 result,再 print(result)。

输出应该是:

8
💡 提示(3 条)
  1. 用 def 关键字定义函数

  2. 函数体里 return a + b

  3. 完整代码:

    def add(a, b):
        return a + b
    
    result = add(3, 5)
    print(result)
    
在编辑器里写这题,跑判分、看参考答案去闯关页做这题 →
教学 03 / 05

二、函数返回值

return 语句用于退出函数,并向调用方返回一个值。

不带值的 return 等同于返回 None。

python到闯关页运行这段 →
def add(num1, num2):
    return num1 + num2

result = add(1, 2)
print(result)

输出:

3

函数也可以返回多个值

python到闯关页运行这段 →
def division(num1, num2):
    """求商与余数"""
    a = num1 % num2
    b = (num1 - a) / num2
    return b, a

quotient, remainder = division(9, 4)
print(quotient, remainder)

t = division(9, 4)
print(t)

输出:

2.0 1
(2.0, 1)

观察一下——函数 return b, a 实际上是返回了一个元组(tuple)(b, a),调用方可以直接「解包」赋给两个变量,也可以整个拿到一个 tuple。

💡 「Python 一次接受多个返回值的数据类型就是元组。」这是相比其他语言的一个简便特性。

练习 2 / 5多返回值

请定义函数 min_max(nums),接收一个 list,返回最小值和最大值两个数(用逗号 return)。

然后调用 min_max([3, 1, 4, 1, 5, 9, 2, 6]),把结果解包到 lo 和 hi 两个变量,再 print(lo) 和 print(hi)。

输出应该是:

1
9
💡 提示(3 条)
  1. 用 return min(nums), max(nums) 一次返回两个值(实际上是 tuple)

  2. 解包:lo, hi = min_max(...)

  3. 完整代码:

    def min_max(nums):
        return min(nums), max(nums)
    
    lo, hi = min_max([3, 1, 4, 1, 5, 9, 2, 6])
    print(lo)
    print(hi)
    
在编辑器里写这题,跑判分、看参考答案去闯关页做这题 →
教学 04 / 05

三、函数的参数

Python 函数对参数的支持非常灵活。这里讲三种最常用的:默认参数、关键字参数、不定长参数。

1、默认参数

调用时可以不传,就用默认值。

python到闯关页运行这段 →
def greet(name, greeting='你好'):
    print(f'{greeting}, {name}!')

greet('两点水')              # 用默认值
greet('两点水', '早上好')    # 覆盖默认值

输出:

你好, 两点水!
早上好, 两点水!

⚠️ 默认值必须是不可变对象(数字 / 字符串 / None / tuple)。别用 list 或 dict 做默认值——会引发非常诡异的 bug。需要默认空 list 时用 None 替代:

python到闯关页运行这段 →
def f(items=None):
    if items is None:
        items = []
    ...

2、关键字参数

调用时按 参数名=值 的形式传,顺序就不重要了。

python到闯关页运行这段 →
def info(name, age, city):
    print(f'{name}, {age} 岁, 来自 {city}')

# 按位置传:要严格按顺序
info('两点水', 18, '广州')

# 按名字传:顺序无所谓
info(age=18, city='广州', name='两点水')

两次输出一样。关键字参数让长参数列表的函数更易读。

3、不定长参数:*args 和 **kwargs

如果调用方传的参数个数不确定,用 *args(接收成 tuple)或 **kwargs(接收成 dict)。

python到闯关页运行这段 →
def sum_all(*nums):
    total = 0
    for n in nums:
        total = total + n
    return total

print(sum_all(1, 2, 3))
print(sum_all(1, 2, 3, 4, 5, 6))

输出:

6
21

*nums 把所有传入的参数收成一个 tuple,函数里就能用 for 遍历。

**kwargs 类似但收成 dict(少用,先跳过,后面真用到再深入)。

练习 3 / 5默认参数

请定义函数 greet(name, greeting='Hello'):第一个参数 name 必传,第二个参数 greeting 默认为 'Hello'。函数体打印 f'{greeting}, {name}!'。

然后:

  1. 调用 greet('Alice')(用默认 greeting)
  2. 调用 greet('Bob', '早上好')(覆盖默认值)

输出应该是:

Hello, Alice!
早上好, Bob!
💡 提示(3 条)
  1. 默认参数写法:def greet(name, greeting='Hello'):

  2. 调用时不传第二个参数会用默认值

  3. 完整代码:

    def greet(name, greeting='Hello'):
        print(f'{greeting}, {name}!')
    
    greet('Alice')
    greet('Bob', '早上好')
    
在编辑器里写这题,跑判分、看参考答案去闯关页做这题 →
练习 4 / 5*args:可变参数

请定义函数 total(*nums),把传入的所有数字加起来返回。

然后:

  1. 调用 total(1, 2, 3) 赋给 a
  2. 调用 total(1, 2, 3, 4, 5, 6) 赋给 b
  3. print(a) print(b)

输出应该是:

6
21
💡 提示(3 条)
  1. *nums 接收任意多个参数收成 tuple

  2. 函数体里 for n in nums 遍历累加,或者直接 return sum(nums)

  3. 完整代码:

    def total(*nums):
        s = 0
        for n in nums:
            s = s + n
        return s
    
    a = total(1, 2, 3)
    b = total(1, 2, 3, 4, 5, 6)
    print(a)
    print(b)
    
在编辑器里写这题,跑判分、看参考答案去闯关页做这题 →
教学 05 / 05

四、匿名函数 lambda

有没有想过定义一个很短的回调函数,但又不想用 def 写一个那么长的形式呢?

Python 用 lambda 创建匿名函数——一行表达式搞定。

基本语法

python到闯关页运行这段 →
lambda 参数: 表达式

例子:

python到闯关页运行这段 →
add = lambda a, b: a + b
print(add(3, 4))

输出:

7

匿名函数 vs 普通函数

python到闯关页运行这段 →
# 普通函数
def add(a, b):
    return a + b

# 等价的 lambda
add = lambda a, b: a + b

两种写法效果完全一样。

适合 lambda 的场景

lambda 最常见的用法是当作参数传给别的函数,比如 sorted 的 key:

python到闯关页运行这段 →
users = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Carol', 'age': 28},
]

# 按年龄排序——临时写个 lambda 当 key
sorted_users = sorted(users, key=lambda u: u['age'])

for u in sorted_users:
    print(u['name'], u['age'])

输出:

Bob 25
Carol 28
Alice 30

lambda 的限制

⚠️ lambda 表达式只能是一个表达式——不能写 if/else 多分支(虽然能写三元表达式)、不能写循环、不能写 return。

如果逻辑稍复杂一点,老老实实用 def,不要硬塞进 lambda。

练习 5 / 5lambda:用匿名函数排序

已经给你定义了:

users = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Carol', 'age': 28},
]

请用 sorted 加 lambda 把 users 按 age 升序排序,赋给 sorted_users,然后用 for 循环依次 print 每个人的 name 和 age(用空格分隔)。

输出应该是:

Bob 25
Carol 28
Alice 30
💡 提示(3 条)
  1. sorted 的 key 参数接收一个函数:每个元素拿来生成「排序依据」

  2. lambda u: u['age'] 等价于 def f(u): return u['age']

  3. 完整代码:

    users = [
        {'name': 'Alice', 'age': 30},
        {'name': 'Bob', 'age': 25},
        {'name': 'Carol', 'age': 28},
    ]
    sorted_users = sorted(users, key=lambda u: u['age'])
    for u in sorted_users:
        print(u['name'], u['age'])
    
在编辑器里写这题,跑判分、看参考答案去闯关页做这题 →

读完了?动手练一遍才算真会。

去闯关模式练习 →