一、为什么需要函数?
问题:同一段代码写了 10 遍,改一处要改 10 处。
解决:把代码封装成函数,需要时调用即可。
函数的好处:
- 代码复用——写一次,用多次
- 模块化——分工明确,易于维护
- 抽象——隐藏实现细节,只关心「做什么」
二、函数的定义与调用
2.1 基本语法
def 函数名(参数1, 参数2, ...):
"""文档字符串(说明函数功能)"""
函数体
return 返回值 # 可选
2.2 示例
def greet(name):
"""向用户打招呼"""
print(f"Hello, {name}!")
greet("张三") # 调用
help(greet) # 查看文档
2.3 定义函数的规则
- 函数名是标识符,遵循命名规范
- 函数名后必须有
() - 函数体必须缩进
- 用
return返回结果;没有 return 则返回None
三、参数详解(重点)
3.1 形参与实参
def add(a, b): # a, b 是形参(形式参数)
return a + b
add(3, 5) # 3, 5 是实参(实际参数)
3.2 位置参数与关键字参数
def info(name, age, city):
print(f"{name}, {age}岁, {city}")
info("张三", 20, "北京") # 位置参数
info(name="李四", age=22, city="上海") # 关键字参数
info("王五", city="广州", age=25) # 混合(位置在前)
3.3 默认参数
def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")
greet("张三") # Hello, 张三!
greet("李四", "Hi") # Hi, 李四!
⚠️ 默认参数不要用可变对象:
# 错误!
def bad(lst=[]):
lst.append(1)
return lst
# 正确
def good(lst=None):
if lst is None:
lst = []
lst.append(1)
return lst
3.4 不定长参数 *args
def total(*args):
print(args) # 元组
return sum(args)
total(1, 2, 3, 4) # 10
3.5 不定长关键字参数 **kwargs
def show(**kwargs):
print(kwargs) # 字典
show(name="张三", age=20)
# {'name': '张三', 'age': 20}
3.6 参数顺序
def func(a, b, c=0, *args, **kwargs):
pass
# 顺序:位置参数 → 默认参数 → *args → **kwargs
3.7 解包传参
def add(a, b, c):
return a + b + c
add(*[1, 2, 3]) # 序列解包
add(**{"a": 1, "b": 2, "c": 3}) # 字典解包
3.8 参数传递机制
Python 是对象引用传递:
- 不可变对象(int、str、tuple):函数内修改不影响外部
- 可变对象(list、dict):函数内修改会影响外部
def modify(lst):
lst.append(4)
nums = [1, 2, 3]
modify(nums)
print(nums) # [1, 2, 3, 4]
四、返回值
def get_min_max(nums):
return min(nums), max(nums) # 返回元组
minimum, maximum = get_min_max([3, 1, 4, 1, 5])
print(minimum, maximum) # 1 5
# 没有 return 返回 None
def do_nothing():
pass
print(do_nothing()) # None
五、函数嵌套调用
def square(x):
return x ** 2
def sum_of_squares(a, b):
return square(a) + square(b)
print(sum_of_squares(3, 4)) # 25
六、变量作用域
6.1 局部变量与全局变量
x = 10 # 全局变量
def func():
x = 20 # 局部变量,不影响全局
print(x) # 20
func()
print(x) # 10
6.2 global 关键字
count = 0
def increment():
global count
count += 1
increment()
print(count) # 1
6.3 nonlocal 关键字
def outer():
x = 10
def inner():
nonlocal x
x = 20
inner()
print(x) # 20
outer()
6.4 LEGB 规则
查找变量名的顺序:Local → Enclosing → Global → Built-in
七、递归
函数调用自身,必须有终止条件。
def factorial(n):
if n <= 1:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 120
递归三要素:
- 终止条件(递归出口)
- 递归公式
- 每次递归向终止条件靠近
八、匿名函数 lambda
# 语法:lambda 参数: 表达式
square = lambda x: x ** 2
print(square(5)) # 25
# 常用于 sorted 的 key
students = [("张三", 85), ("李四", 92), ("王五", 78)]
students.sort(key=lambda s: s[1], reverse=True)
print(students)
九、练习题
基础题
1. 编写 is_prime(n) 判断素数。
2. 编写函数,接收任意个数数字,返回平均值。
3. 编写函数,返回字符串中 (大写个数, 小写个数, 数字个数)。
4. 用 lambda 将 [("apple",3),("ban",2)] 按数量降序排列。
5. 编写递归函数求 1+2+...+n。
进阶题
6. 实现二分查找(递归版)。
7. 编写装饰器 @timer 打印函数执行耗时。
参考答案
点击展开参考答案
import time
def is_prime(n):
if n < 2: return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0: return False
return True
def average(*args):
return sum(args) / len(args) if args else 0
def count_chars(s):
return (sum(1 for c in s if c.isupper()),
sum(1 for c in s if c.islower()),
sum(1 for c in s if c.isdigit()))
def sum_n(n):
if n <= 0: return 0
return n + sum_n(n - 1)
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"{func.__name__} 耗时: {time.time()-start:.4f}s")
return result
return wrapper

1599

被折叠的 条评论
为什么被折叠?



