🍬 Python语法糖完全指南

让代码更优雅、更Pythonic的语法特性详解

数据类型相关的语法糖

📝列表推导式 (List Comprehension)

用简洁的语法创建列表,替代传统的for循环

💡 基本用法
# 传统方式
squares = []
for i in range(10):
    squares.append(i ** 2)

# 语法糖方式(列表推导式)
squares = [i ** 2 for i in range(10)]

# 带条件的列表推导式
even_squares = [i ** 2 for i in range(10) if i % 2 == 0]
🔄 嵌套列表推导式
# 创建一个5x5的矩阵
matrix = [[i * 5 + j for j in range(5)] for i in range(5)]

# 展平嵌套列表
nested = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for sublist in nested for num in sublist]

📚字典推导式 (Dictionary Comprehension)

快速创建和操作字典的优雅方式

# 创建平方数字典
squares_dict = {i: i ** 2 for i in range(5)}
# 结果: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 交换字典的键和值
original = {'a': 1, 'b': 2, 'c': 3}
swapped = {value: key for key, value in original.items()}

# 过滤字典
scores = {'Alice': 85, 'Bob': 92, 'Charlie': 78}
high_scores = {name: score for name, score in scores.items() if score >= 90}

🎯集合推导式 (Set Comprehension)

创建集合的简洁语法,自动去重

# 从列表创建集合(自动去重)
numbers = [1, 2, 2, 3, 3, 4, 5]
unique_squares = {i ** 2 for i in numbers}
# 结果: {1, 4, 9, 16, 25}

# 提取字符串中的所有唯一字符
text = "hello world"
unique_chars = {char for char in text if char != ' '}

📦解包操作 (Unpacking)

* 和 ** 运算符的妙用

# 列表/元组解包
first, *middle, last = [1, 2, 3, 4, 5]
# first = 1, middle = [2, 3, 4], last = 5

# 合并列表
list1 = [1, 2, 3]
list2 = [4, 5, 6]
merged = [*list1, *list2]
# 结果: [1, 2, 3, 4, 5, 6]

# 字典解包
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged_dict = {**dict1, **dict2}

# 函数参数解包
def add(a, b, c):
    return a + b + c

args = [1, 2, 3]
result = add(*args)  # 解包列表作为位置参数

kwargs = {'a': 1, 'b': 2, 'c': 3}
result = add(**kwargs)  # 解包字典作为关键字参数

✂️切片操作 (Slicing)

强大的序列切片功能

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

# 基本切片
numbers[2:5]    # [2, 3, 4]
numbers[:3]     # [0, 1, 2]
numbers[7:]     # [7, 8, 9]
numbers[::2]    # [0, 2, 4, 6, 8] 步长为2
numbers[::-1]   # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] 反转

# 切片赋值
numbers[2:5] = [20, 30, 40]  # 替换切片部分
numbers[::2] = [0, 0, 0, 0, 0]  # 间隔赋值

# 浅拷贝
copy_of_numbers = numbers[:]

💎f-string (格式化字符串)

Python 3.6+ 引入的强大字符串格式化方式

name = "Alice"
age = 30

# 基本用法
greeting = f"Hello, {name}! You are {age} years old."

# 表达式
result = f"2 + 3 = {2 + 3}"

# 调用方法
text = "hello"
formatted = f"{text.upper()} world!"

# 格式化数字
pi = 3.1415926
formatted_pi = f"π = {pi:.2f}"  # π = 3.14

# 日期格式化
from datetime import datetime
now = datetime.now()
formatted_date = f"Today is {now:%Y-%m-%d %H:%M:%S}"

# 调试模式 (Python 3.8+)
x = 10
debug = f"{x = }"  # 'x = 10'
运算操作相关的语法糖

🌊海象运算符 (Walrus Operator)

Python 3.8+ 引入的 := 运算符,在表达式中同时进行赋值和返回

# 传统方式
data = get_data()
if data:
    process(data)

# 使用海象运算符
if (data := get_data()):
    process(data)

# 在列表推导式中使用
# 过滤出长度大于5且转换为大写后的字符串
words = ["hello", "world", "python", "code"]
result = [upper for word in words if len(upper := word.upper()) > 5]

# 在while循环中使用
while (chunk := file.read(1024)):
    process(chunk)

🔗链式比较 (Chained Comparisons)

连续比较操作的优雅写法

# 传统方式
if x > 0 and x < 10:
    pass

# 链式比较(更Pythonic)
if 0 < x < 10:
    pass

# 更多例子
if 0 <= score <= 100:
    print("Valid score")

# 检查是否在所有边界内
if 1 < x <= 5 < y <= 10:
    pass

🔀三元表达式 (Ternary Expression)

简洁的条件赋值

# 传统方式
if condition:
    x = 'true'
else:
    x = 'false'

# 三元表达式
x = 'true' if condition else 'false'

# 实际应用
age = 20
status = "成年" if age >= 18 else "未成年"

# 嵌套三元表达式(谨慎使用,可读性下降)
grade = "优秀" if score >= 90 else "良好" if score >= 80 else "及格" if score >= 60 else "不及格"

运算符重载 (Operator Overloading)

自定义类的运算符行为

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    # 重载 + 运算符
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

    # 重载 * 运算符(标量乘法)
    def __mul__(self, scalar):
        return Vector(self.x * scalar, self.y * scalar)

    # 重载字符串表示
    def __str__(self):
        return f"Vector({self.x}, {self.y})"

    # 重载比较运算符
    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

# 使用
v1 = Vector(1, 2)
v2 = Vector(3, 4)
v3 = v1 + v2  # 调用 __add__
v4 = v1 * 3   # 调用 __mul__
print(v3)  # Vector(4, 6)
函数相关的语法糖

🎭装饰器 (Decorators)

在不修改原函数的情况下增强函数功能

# 基本装饰器
def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

# 带参数的装饰器
def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator

@repeat(times=3)
def greet(name):
    print(f"Hello, {name}!")

# 类装饰器
class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0

    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Call count: {self.count}")
        return self.func(*args, **kwargs)

@CountCalls
def say_hi():
    print("Hi!")

📦with语句 (上下文管理器)

自动管理资源,确保清理操作执行

# 传统方式
file = open('file.txt', 'r')
try:
    data = file.read()
finally:
    file.close()

# 使用 with 语句(语法糖)
with open('file.txt', 'r') as file:
    data = file.read()
# 自动关闭文件

# 自定义上下文管理器
class MyContext:
    def __enter__(self):
        print("Entering context")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting context")
        return False  # 不抑制异常

with MyContext() as ctx:
    print("Inside context")

# 使用 contextlib(更简洁)
from contextlib import contextmanager

@contextmanager
def my_context():
    print("Entering")
    yield "resource"
    print("Exiting")

with my_context() as resource:
    print(f"Using {resource}")

🏭生成器 (Generators)

惰性计算,节省内存的迭代器

# 生成器函数
def count_up_to(n):
    i = 0
    while i < n:
        yield i
        i += 1

# 使用生成器
for num in count_up_to(5):
    print(num)  # 0, 1, 2, 3, 4

# 生成器表达式(类似列表推导式,但使用圆括号)
squares = (i ** 2 for i in range(10))
print(next(squares))  # 0
print(next(squares))  # 1

# 内存对比
# 列表:立即在内存中创建所有元素
list_comp = [i ** 2 for i in range(1000000)]  # 占用大量内存

# 生成器:按需生成,几乎不占内存
gen_exp = (i ** 2 for i in range(1000000))  # 占用极少内存

# yield from 语法 (Python 3.3+)
def sub_gen():
    yield 1
    yield 2
    yield 3

def main_gen():
    yield "start"
    yield from sub_gen()  # 委托给子生成器
    yield "end"

🎯Lambda表达式 (匿名函数)

创建小型匿名函数的简洁方式

# 传统函数
def add(x, y):
    return x + y

# Lambda表达式
add = lambda x, y: x + y

# 在高阶函数中使用
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
filtered = list(filter(lambda x: x % 2 == 0, numbers))
sorted_by_abs = sorted([-3, 1, -2, 5], key=lambda x: abs(x))

# 配合三元表达式
max_value = lambda a, b: a if a > b else b

# 闭包示例
def make_multiplier(n):
    return lambda x: x * n

double = make_multiplier(2)
triple = make_multiplier(3)
print(double(5))  # 10
print(triple(5))  # 15
控制流相关的语法糖

🔄for-else 和 while-else

循环正常完成后执行else块(未被break中断)

# for-else 示例
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num == 0:
        print("Found zero!")
        break
else:
    print("No zero found in the list")  # 这行会执行

# 实际应用:查找质数
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

# 使用 for-else 查找质数
for n in range(2, 20):
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            break
    else:
        print(f"{n} is prime")

🎯条件表达式中的短路求值

利用and和or的短路特性

# 短路求值
# and: 如果第一个为False,不评估第二个
# or: 如果第一个为True,不评估第二个

# 安全访问嵌套字典
data = {'user': {'name': 'Alice'}}
name = data.get('user') and data['user'].get('name')

# 默认值模式(类似其他语言的 ?? 或 ||)
# 注意:这只在左侧为False时有效
username = provided_name or "Guest"

# 更安全的默认值(使用海象运算符或条件表达式)
username = provided_name if provided_name is not None else "Guest"

# 函数调用中的短路
condition and do_something()  # 只有condition为True时才调用
condition or do_fallback()  # 只有condition为False时才调用

📋切片赋值和删除

使用切片进行批量操作和修改

numbers = [1, 2, 3, 4, 5]

# 切片赋值
numbers[1:3] = [20, 30]  # [1, 20, 30, 4, 5]
numbers[:2] = [10, 20, 30]  # 可改变长度 [10, 20, 30, 30, 4, 5]

# 插入元素(不删除)
numbers[2:2] = [99, 99]  # 在索引2处插入

# 删除切片
numbers[1:3] = []  # 删除索引1和2的元素
del numbers[::2]  # 删除所有偶数索引的元素

# 替换所有元素
numbers[:] = [1, 2, 3]  # 修改原列表,而不是创建新列表
高级语法特性

🚀异步语法 (Async/Await)

Python 3.5+ 引入的异步编程语法

import asyncio

# 异步函数
async def fetch_data(url):
    print(f"Fetching {url}...")
    await asyncio.sleep(1)  # 模拟IO操作
    return f"Data from {url}"

# 并发执行多个异步任务
async def main():
    # 顺序执行
    result1 = await fetch_data("url1")
    result2 = await fetch_data("url2")

    # 并发执行
    results = await asyncio.gather(
        fetch_data("url1"),
        fetch_data("url2"),
        fetch_data("url3")
    )
    return results

# 运行异步函数
asyncio.run(main())

# 异步上下文管理器 (Python 3.7+)
class AsyncContext:
    async def __aenter__(self):
        print("Entering async context")
        return self

    async def __aexit__(self, exc_type, exc, tb):
        print("Exiting async context")

async def use_async_context():
    async with AsyncContext() as ctx:
        print("Inside async context")

🎨类型提示 (Type Hints)

Python 3.5+ 的类型注解语法

from typing import List, Dict, Optional, Tuple, Union

# 基本类型提示
def greet(name: str, age: int) -> str:
    return f"Hello {name}, you are {age} years old"

# 复杂类型
def process_data(
    items: List[int],
    mapping: Dict[str, int],
    optional_value: Optional[float] = None
) -> Tuple[int, str]:
    pass

# Union类型 (Python 3.10+ 可以用 X | Y)
def handle_id(id: Union[int, str]) -> str:
    return str(id)

# Python 3.10+ 的新语法
def handle_id_new(id: int | str) -> str:
    return str(id)

# 类型别名
Vector = List[float]

def scale(vector: Vector, scalar: float) -> Vector:
    return [x * scalar for x in vector]

# 泛型 (Python 3.9+)
from typing import TypeVar, Generic

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self):
        self._items: List[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

🔥结构模式匹配 (Structural Pattern Matching)

Python 3.10+ 引入的match-case语法,类似其他语言的switch-case但更强大

# 基本匹配
def http_status(status: int) -> str:
    match status:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500:
            return "Internal Server Error"
        case _:
            return "Unknown Status"

# 解构匹配
point = (3, 5)
match point:
    case (0, 0):
        print("Origin")
    case (0, y):
        print(f"On Y axis at {y}")
    case (x, 0):
        print(f"On X axis at {x}")
    case (x, y):
        print(f"Point at ({x}, {y})")

# 带条件的匹配(守护条件)
match point:
    case (x, y) if x == y:
        print("On diagonal")
    case (x, y):
        print(f"Point ({x}, {y})")

# 匹配对象属性
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)
match p:
    case Point(x=0, y=0):
        print("Origin")
    case Point(x=0, y=y):
        print(f"On Y axis at {y}")
    case Point(x=x, y=y):
        print(f"Point at ({x}, {y})")

walrus运算符高级用法

在更多场景中使用海象运算符简化代码

# 在while循环中使用
while (chunk := file.read(1024)) != "":
    process(chunk)

# 在列表推导式中使用
# 过滤出长度大于5且大写的字符串
words = ["hello", "world", "python", "code"]
result = [upper for word in words if len(upper := word.upper()) > 5]

# 在推导式中避免重复计算
# 传统方式(计算两次)
squares = [x**2 for x in range(10) if x**2 > 25]

# 使用海象运算符(计算一次)
squares = [sq for x in range(10) if (sq := x**2) > 25]

# 在条件表达式中使用
def process(data):
    if (result := expensive_computation(data)) is not None:
        return result
    return fallback()
💡 提示:海象运算符在很多情况下可以让代码更简洁,但要避免过度使用导致可读性下降。在列表推导式和while循环中特别有用。
内置工具和实用特性

📦Import 导入技巧

Python灵活的模块导入语法

# 基本导入
import os
import sys, os  # 同时导入多个(不推荐)

# 从模块导入特定对象
from math import sqrt, pi
from datetime import datetime as dt  # 使用别名

# 导入所有(不推荐在生产代码中使用)
from math import *  # 导入所有公开对象

# 相对导入(在包内使用)
from . import sibling_module
from ..parent import module

# 条件导入
try:
    import numpy as np
except ImportError:
    np = None

# 动态导入 (Python 3.7+)
import importlib
module = importlib.import_module('math')

# __all__ 控制导出
# 在 module.py 中定义:
# __all__ = ['public_func1', 'public_func2']
# 只有列出的名称会被 `from module import *` 导入

# if __name__ == "__main__" 惯用法
if __name__ == "__main__":
    # 只有直接运行此文件时才会执行
    main()

📖字典的实用方法

dict.get(), setdefault(), update() 等方法让字典操作更安全、更简洁

# get() - 安全获取值,避免KeyError
data = {'a': 1, 'b': 2}

# 传统方式(容易抛出KeyError)
try:
    value = data['c']
except KeyError:
    value = 'default'

# 使用get()(语法糖)
value = data.get('c', 'default')  # 'default'

# setdefault() - 如果键不存在,设置默认值
# 传统方式
if 'key' not in data:
    data['key'] = []
data['key'].append(1)

# 使用setdefault()(更简洁)
data.setdefault('key', []).append(1)

# update() - 批量更新
data.update({'c': 3, 'd': 4})
data.update(e=5, f=6)  # 关键字参数形式

# defaultdict - 自动初始化默认值
from collections import defaultdict
dd = defaultdict(list)  # 访问不存在的键时,自动创建空列表
dd['new_key'].append(1)  # 不需要先检查或初始化

dd_int = defaultdict(int)  # 默认值为0
dd_int['count'] += 1  # 直接累加

# dict() 构造函数技巧
# 从键值对列表创建
pairs = [('a', 1), ('b', 2)]
dict(pairs)  # {'a': 1, 'b': 2}

# 从两个列表创建
keys = ['a', 'b', 'c']
values = [1, 2, 3]
dict(zip(keys, values))  # {'a': 1, 'b': 2, 'c': 3}

# 合并字典 (Python 3.9+)
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged = dict1 | dict2  # 使用 | 运算符 (Python 3.9+)
dict1 |= dict2  # 原地合并 (Python 3.9+)

🎯集合运算 (Set Operations)

集合的操作符重载,让集合运算更直观

# 创建集合
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}

# 并集 (Union) - 使用 | 运算符
union = set1 | set2  # {1, 2, 3, 4, 5, 6}
union_method = set1.union(set2)  # 等价方法

# 交集 (Intersection) - 使用 & 运算符
intersection = set1 & set2  # {3, 4}
intersection_method = set1.intersection(set2)

# 差集 (Difference) - 使用 - 运算符
difference = set1 - set2  # {1, 2} (在set1但不在set2中)
difference_method = set1.difference(set2)

# 对称差集 (Symmetric Difference) - 使用 ^ 运算符
symmetric_diff = set1 ^ set2  # {1, 2, 5, 6} (只在一个集合中)
sym_diff_method = set1.symmetric_difference(set2)

# 原地操作
set1 |= set2   # 原地并集
set1 &= set2   # 原地交集
set1 -= set2   # 原地差集
set1 ^= set2   # 原地对称差集

# 子集和超集判断
small = {1, 2}
large = {1, 2, 3, 4}
small <= large  # True (子集)
large >= small  # True (超集)
small < large   # True (真子集)

# 成员检测(比列表快得多)
if 3 in set1:  # O(1) 平均时间复杂度
    print("Found!")

# 集合推导式(之前已介绍)
squared_set = {x**2 for x in range(10)}

🔄多重赋值和链式赋值

Python中优雅的赋值语法

# 多重赋值(解包赋值)
a, b = 1, 2
# 等价于:
# a = 1
# b = 2

# 交换变量(不需要临时变量!)
a, b = b, a  # 经典语法糖

# 链式赋值
a = b = c = 0  # 三个变量都赋值为0
# 注意:对于可变对象要小心!
list1 = list2 = []  # 两个变量引用同一个列表!
list1.append(1)
print(list2)  # [1] - 意想不到的结果

# 增量赋值运算符
x = 10
x += 5   # x = x + 5
x -= 3   # x = x - 3
x *= 2   # x = x * 2
x /= 4   # x = x / 4
x //= 2  # x = x // 2 (整除)
x **= 3  # x = x ** 3 (幂运算)
x %= 3   # x = x % 3 (取模)

# 对于列表
lst = [1, 2, 3]
lst += [4, 5]  # 等价于 lst.extend([4, 5])
lst *= 2  # [1, 2, 3, 1, 2, 3]

# 解包赋值的高级用法
(a, b), (c, d) = (1, 2), (3, 4)  # a=1, b=2, c=3, d=4
head, *tail = [1, 2, 3, 4, 5]  # head=1, tail=[2, 3, 4, 5]

🔢迭代工具 (enumerate, zip, sorted)

让循环和迭代更Pythonic的内置函数

# enumerate() - 同时获取索引和值
fruits = ['apple', 'banana', 'cherry']

# 传统方式
for i in range(len(fruits)):
    print(i, fruits[i])

# 使用enumerate()(更优雅)
for i, fruit in enumerate(fruits):
    print(i, fruit)

# 指定起始索引
for i, fruit in enumerate(fruits, start=1):
    print(i, fruit)  # 从1开始计数

# zip() - 并行迭代多个序列
names = ['Alice', 'Bob', 'Charlie']
scores = [85, 92, 78]
for name, score in zip(names, scores):
    print(f"{name}: {score}")

# zip() 的不等长处理
from itertools import zip_longest
for item in zip_longest([1, 2, 3], ['a', 'b'], fillvalue='default'):
    print(item)  # (1, 'a'), (2, 'b'), (3, 'default')

# sorted() - 排序(返回新列表,不修改原列表)
numbers = [3, 1, 4, 1, 5, 9, 2]
sorted_numbers = sorted(numbers)  # [1, 1, 2, 3, 4, 5, 9]
sorted_desc = sorted(numbers, reverse=True)  # 降序

# 按自定义键排序
students = [
    {'name': 'Alice', 'score': 85},
    {'name': 'Bob', 'score': 92},
    {'name': 'Charlie', 'score': 78}
]
sorted_by_score = sorted(students, key=lambda x: x['score'])

# reversed() - 反转序列
for num in reversed([1, 2, 3, 4, 5]):
    print(num)  # 5, 4, 3, 2, 1

# 组合使用
data = [(1, 'b'), (3, 'a'), (2, 'c')]
# 先按第二个元素排序,再按第一个元素排序
sorted_data = sorted(data, key=lambda x: (x[1], x[0]))

🎨属性装饰器 (@property)

将方法变为属性访问,实现getter/setter的优雅语法

# 传统getter/setter
class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius

    def get_celsius(self):
        return self._celsius

    def set_celsius(self, value):
        if value < -273.15:
            self._celsius = value
        else:
            raise ValueError("Temperature below absolute zero!")

# 使用 @property (语法糖)
class Temperature:
    def __init__(self, celsius=0):
        self._celsius = celsius

    @property
    def celsius(self):
        """Getter"""
        return self._celsius

    @celsius.setter
    def celsius(self, value):
        """Setter"""
        if value < -273.15:
            self._celsius = value
        else:
            raise ValueError("Temperature below absolute zero!")

    @property
    def fahrenheit(self):
        """只读属性"""
        return self._celsius * 9/5 + 32

# 使用(像访问属性一样,但实际上调用了方法)
temp = Temperature(25)
print(temp.celsius)   # 调用getter
temp.celsius = 30       # 调用setter
print(temp.fahrenheit) # 调用getter(只读)

# @staticmethod 和 @classmethod
class MathUtils:
    @staticmethod
    def add(a, b):
        """静态方法:不需要self或cls"""
        return a + b

    @classmethod
    def from_string(cls, s):
        """类方法:第一个参数是类本身"""
        a, b = map(int, s.split(','))
        return cls(a, b)

    def __init__(self, a, b):
        self.a = a
        self.b = b

# 使用
result = MathUtils.add(1, 2)  # 不需要实例化
instance = MathUtils.from_string("3,4")  # 工厂方法

📊数据类 (dataclass 和 namedtuple)

自动生成__init__、__repr__等方法的语法糖

# 传统类定义
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

# 使用 @dataclass (Python 3.7+)
from dataclasses import dataclass

@dataclass
class Point:
    x: float
    y: float

# 自动生成 __init__, __repr__, __eq__ 等方法
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1)  # Point(x=1, y=2)
print(p1 == p2)  # True

# dataclass的高级用法
@dataclass
class User:
    name: str
    email: str
    age: int = 0  # 默认值
    active: bool = True

    def greet(self):
        return f"Hello, {self.name}!"

# namedtuple - 轻量级不可变数据类
from collections import namedtuple

Point = namedtuple('Point', ['x', 'y''])
p = Point(1, 2)
print(p.x, p.y)  # 1 2
# p.x = 3  # 错误!namedtuple是不可变的

# namedtuple的现代替代:typing.NamedTuple
from typing import NamedTuple

class Point(NamedTuple):
    x: float
    y: float

    def distance_from_origin(self):
        return (self.x ** 2 + self.y ** 2) ** 0.5
💡 选择建议:
  • @dataclass:需要可变对象,或需要自定义方法
  • namedtuple:需要不可变对象,且不需要自定义方法
  • typing.NamedTuple:需要不可变对象,但需要类型提示和自定义方法

functools 实用工具

函数式编程工具和性能优化装饰器

from functools import lru_cache, partial, reduce

# @lru_cache - 自动缓存函数结果(记忆化)
# 非常适合递归函数,如斐波那契数列
@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))  # 非常快,因为使用了缓存

# partial - 固定部分参数,创建新函数
def power(base, exponent):
    return base ** exponent

square = partial(power, exponent=2)
cube = partial(power, exponent=3)

print(square(5))  # 25
print(cube(5))    # 125

# reduce - 累积计算(Python 3中移至functools)
from functools import reduce

# 计算阶乘
factorial = reduce(lambda x, y: x * y, range(1, 6))  # 120

# 等价于
result = 1
for i in range(1, 6):
    result *= i

# @wraps - 保留被装饰函数的元数据
from functools import wraps

def my_decorator(func):
    @wraps(func)  # 保留原函数的名称、文档字符串等
    def wrapper(*args, **kwargs):
        """Wrapper function"""
        print("Before")
        result = func(*args, **kwargs)
        print("After")
        return result
    return wrapper

@my_decorator
def greet(name):
    """Greet someone"""
    print(f"Hello, {name}!")

print(greet.__name__)  # 'greet' (而不是 'wrapper')
print(greet.__doc__)   """Greet someone"""

🚀__slots__ 内存优化

通过固定属性来大幅减少内存使用

# 普通类 - 使用 __dict__ 存储属性(内存开销大)
class NormalUser:
    def __init__(self, name, age):
        self.name = name
        self.age = age

user1 = NormalUser("Alice", 30)
user1.new_attr = "dynamic"  # 可以动态添加属性

# 使用 __slots__ - 禁止动态属性,节省内存
class OptimizedUser:
    __slots__ = ('name', 'age')  # 只允许这两个属性

    def __init__(self, name, age):
        self.name = name
        self.age = age

user2 = OptimizedUser("Bob", 25)
# user2.new_attr = "test"  # 错误!不能动态添加属性

# 内存对比
import sys
user1_size = sys.getsizeof(user1.__dict__)  # 较大的开销
user2_size = sys.getsizeof(user2)  # 小得多的开销

# __slots__ 的注意事项
# 1. 子类也会继承 __slots__ 的限制
# 2. 每个子类也需要定义自己的 __slots__ 才能继续优化
# 3. 不适合需要动态属性的场景
# 4. 在创建大量实例时(如数百万个),内存节省非常显著

# 实际应用示例
class Point:
    __slots__ = ('x', 'y')
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 如果有数百万个点,使用 __slots__ 可以节省大量内存
points = [Point(i, i*2) for i in range(1000000)]
💡 使用建议:只有在需要创建大量实例(通常>10万)时才使用 __slots__,否则 __dict__ 的灵活性更有价值。

🎁扩展的可迭代解包 (Extended Iterable Unpacking)

Python 3 中更强大的解包功能

# 在函数定义中使用 *args 和 **kwargs
def func(*args, **kwargs):
    print(f"args: {args}")
    print(f"kwargs: {kwargs}")

func(1, 2, 3, name="Alice", age=30)
# args: (1, 2, 3)
# kwargs: {'name': 'Alice', 'age': 30}

# 在函数调用中解包
def add(a, b, c):
    return a + b + c

args = [1, 2, 3]
print(add(*args))  # 解包列表

kwargs = {"a": 1, "b": 2, "c": 3}
print(add(**kwargs))  # 解包字典

# 在赋值中解包
a, *middle, b = [1, 2, 3, 4, 5]
# a = 1, middle = [2, 3, 4], b = 5

first, *rest = [1, 2, 3, 4, 5]
# first = 1, rest = [2, 3, 4, 5]

*beginning, last = [1, 2, 3, 4, 5]
# beginning = [1, 2, 3, 4], last = 5
📚 学习建议: