在 Python 中,函数是组织代码、实现复用和模块化的核心机制。以下是 Python 函数的详细指南,包括基础语法、高级特性和最佳实践。
1. 函数基础
定义函数
使用 def 关键字定义函数:
# 声明函数
def greet(name):
"""返回问候语"""
return f"Hello, {name}!"
# 调用函数
print(greet("Alice")) # 输出: Hello, Alice!
参数类型
- 位置参数:按顺序传递。
- 默认参数:为参数提供默认值。
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Bob")) # Hello, Bob!
print(greet("Bob", "Hi")) # Hi, Bob!
返回值
- 默认返回
None,或通过return显式返回。 - 可以返回多个值(实际是返回一个元组)。
def calc(a, b):
return a + b, a * b
sum_result, product = calc(3, 4)
2. 参数传递方式
可变参数 (*args 和 **kwargs)
*args:接收任意数量的位置参数,存储为元组。**kwargs:接收任意数量的关键字参数,存储为字典。
def example(a, *args, **kwargs):
print(f"固定参数: {a}")
print(f"额外位置参数: {args}")
print(f"额外关键字参数: {kwargs}")
example(1, 2, 3, x=4, y=5)
# 输出:
# 固定参数: 1
# 额外位置参数: (2, 3)
# 额外关键字参数: {'x': 4, 'y': 5}
强制关键字参数
使用 * 强制后续参数必须通过关键字传递:
def create_user(name, *, age, is_admin=False):
print(f"{name}, {age}, Admin: {is_admin}")
create_user("Alice", age=25) # 正确
create_user("Bob", 30, True) # 报错!
3. 函数作用域
- 局部变量:函数内部定义的变量,外部不可见。
- 全局变量:通过
global关键字修改。
x = 10
def modify_global():
global x
x = 20
modify_global()
print(x) # 输出: 20
4. 高阶函数
函数可以作为参数或返回值:
# 函数作为参数
def apply(func, x, y):
return func(x, y)
print(apply(lambda a, b: a + b, 3, 4)) # 输出: 7
# 函数作为返回值
def make_multiplier(n):
return lambda x: x * n
double = make_multiplier(2)
print(double(5)) # 输出: 10
5. 装饰器 (Decorators)
用于扩展函数功能,不修改原函数代码:
def log_time(func):
import time
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print(f"耗时: {time.time() - start:.2f}s")
return result
return wrapper
@log_time
def heavy_computation():
import time
time.sleep(2)
heavy_computation() # 输出: 耗时: 2.00s
6. 生成器函数
使用 yield 返回迭代器:
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for num in count_up_to(5):
print(num) # 输出: 1 2 3 4 5
7. 递归函数
函数调用自身,需注意递归深度:
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
print(factorial(5)) # 输出: 120
8. 类型注解 (Python 3.5+)
提高代码可读性,配合工具(如 mypy)静态检查:
def add(a: int, b: int) -> int:
return a + b
print(add(3, 4)) # 正确
print(add("3", "4")) # 类型检查会警告(但运行时仍可执行)
9. 文档字符串 (Docstring)
使用三引号添加函数说明:
def calculate_area(radius: float) -> float:
"""计算圆的面积。
Args:
radius: 圆的半径
Returns:
圆的面积(π * r²)
"""
return 3.14159 * radius ** 2
10. 最佳实践
- 函数长度:保持简短(一般不超过一屏)。
- 单一职责:每个函数只做一件事。
- 避免副作用:尽量不修改外部状态。
- 错误处理:使用
try/except或返回错误码。
def divide(a, b):
try:
return a / b
except ZeroDivisionError:
return float('inf')