跳到正文
Joeplover
学习笔记·2026-06-19·约 2 分钟阅读

Python 核心语法扫盲:列表推导式到装饰器

Python 中那些看似简单但容易混淆的语法点——列表推导式、生成器、args/kwargs、装饰器、yield 的完整梳理。

Python 代码

Python 核心语法扫盲:列表推导式到装饰器

背景

工作中常用 Python 写工具脚本和 AI/LLM 项目,但语法细节经常记不住。这份笔记整理了从列表推导式到装饰器的核心语法。

列表推导式

[x*2 for x in range(10) if x%2 == 0]

阅读顺序从右往左:for x in range(10) 循环 → if x%2==0 过滤 → x*2 表达式。等价于:

result = []
for x in range(10):
    if x % 2 == 0:
        result.append(x * 2)

嵌套列表推导式(例如二维数组展平):

# [[1,2],[3,4]] → [1,2,3,4]
[y for x in [[1,2],[3,4]] for y in x]

这里阅读顺序是:外层 for → 内层 for → 表达式。

dict.setdefault() vs update()

一个我常搞混的地方:

# 错误写法
group = {}
for item in data:
    key = item['type']
    group[key] = group.get(key, [])
    group[key].append(item)

# 正确写法
group = {}
for item in data:
    group.setdefault(item['type'], []).append(item)

# setdefault: 如果 key 不存在就设默认值,返回该 key 对应的 value

setdefault 比 get + 赋值更简洁,且保证原子性。

*args 和 **kwargs

def func(*args, **kwargs):
    # args → 元组 (1, 2, 3)
    # kwargs → 字典 {'a': 1, 'b': 2}
    pass

func(1, 2, 3, a=1, b=2)

常见于:装饰器包装、super() 调用父类方法、设计灵活 API。

生成器 yield

def read_large_file(path):
    with open(path) as f:
        for line in f:
            yield line.strip()  # 一次一行,不占内存

生成器 vs 列表:列表一次性生成所有元素放在内存里;生成器惰性求值,用到才出。处理大文件时必须用生成器。

装饰器

装饰器是在不修改原函数代码的前提下添加功能的工具:

def log_time(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} took {time.time()-start:.2f}s")
        return result
    return wrapper

@log_time
def slow_function():
    time.sleep(1)

@log_time 等价于 slow_function = log_time(slow_function)。本质是高阶函数——外层接收函数,内层增强行为。

带参数的装饰器需要多包一层:

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def say_hello():
    print("hello")

总结

Python 的这些语法特性让代码更简洁,但简洁不等于简单。理解底层机制(闭包、高阶函数、惰性求值)才能写出不出 Bug 的 Python 代码。