函数

翻译整理自 Python Tutorial - More on Functions 与 PEP 3102。

1. 函数定义语法

def add(a, b):
    """返回 a+b"""
    return a + b
  • 形参与实参
  • 关键字参数:add(b=2, a=1)
  • 默认值:def f(a=1)
  • 仅位置/仅关键字:def f(pos, /, *, kw)

2. 注解(Annotation)

注解只存储在 __annotations__ 中,运行时不检查,需 mypy、pydantic 校验:

def inc(x: int, step: int = 1) -> int:
    return x + step

print(inc.__annotations__)
# {'x': <class 'int'>, 'step': <class 'int'>, 'return': <class 'int'>}

3. 内置函数

部分常用内置:

函数 用途
len, min, max, sum 序列统计
sorted, reversed 排序/反转
enumerate, zip 配对迭代
map, filter 函数式映射
any, all 任一/全部为真
range 数值序列
isinstance, issubclass 类型判断
getattr, setattr 反射
sorted(["b", "a", "c"])
list(zip([1, 2], ["a", "b"]))   # [(1, 'a'), (2, 'b')]
list(map(str.upper, ["a", "b"]))  # ['A', 'B']

4. 高阶函数

函数是一等公民,可作为参数与返回值:

def make_multiplier(factor):
    def multiply(x):
        return x * factor
    return multiply

double = make_multiplier(2)
double(5)  # 10

闭包与自由变量

def counter():
    count = 0
    def step():
        nonlocal count
        count += 1
        return count
    return step

c = counter()
c(); c(); c()  # 3

5. 装饰器

装饰器是高阶函数的语法糖:

def log(func):
    def wrap(*args, **kwargs):
        print(f"call {func.__name__}")
        return func(*args, **kwargs)
    return wrap

@log
def hello(name):
    print(f"hello, {name}")

hello("Go")
# call hello
# hello, Go

使用 functools.wraps 保留元信息:

from functools import wraps

def log(func):
    @wraps(func)
    def wrap(*args, **kwargs):
        return func(*args, **kwargs)
    return wrap

6. 生成器与 yield

yield 让函数变为生成器,惰性产出:

def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

it = fib()
[next(it) for _ in range(10)]
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

生成器表达式

sum(x * x for x in range(10))

7. 递归

def fact(n):
    return 1 if n <= 1 else n * fact(n - 1)

fact(5)  # 120

Python 默认递归深度 1000,可调 sys.setrecursionlimit,但要注意栈溢出。

小结

函数是 Python 复用代码的基本单位,配合装饰器、生成器、闭包能写出极优雅的代码。