《Python编程入门》附录 A:Python 语法速查表

本附录把全书用到的 Python 语法压缩成一组速查表:字面量与运算符优先级、字符串/列表/字典/集合的常用方法与复杂度、切片与解包、函数参数四种形态、作用域、类与继承、异常语法、match 语句、PEP 695 类型注解、内置函数与 f-string 格式说明符,每个片段均在 3.14.6 上实测。

前面 18 章把「为什么这样设计」讲透了,这一页只做一件事:把写代码时真正会去翻的语法压成表。建议第一次通读建立索引感,之后把它当案头卡片——写的时候不必回忆章节号,先在这里对号入座,再回正文看完整推导。

本附录所有代码片段都在本机 Python 3.14.6 上实际运行过,输出为真实结果。标注了「3.x+」的语法低于该版本会直接报错,其余语法在 3.12 基线上同样可用。

附录 A Python 语法速查表

字面量与数值写法

写法含义备注
42 / -7整数任意精度,没有溢出
1_000_000带下划线的整数下划线只是分隔符,不影响数值
0xFF / 0o17 / 0b1010十六 / 八 / 二进制分别等于 255 / 15 / 10
3.14 / 1.5e3浮点1.5e3 == 1500.0;二进制浮点有精度误差
2j / 3+4j复数虚部带 j,实部虚部都是浮点
True / False / None布尔与空值三者都是单例,用 is 比较
"a" / 'a' / """a"""字符串三种引号等价;三引号可跨行
r"a\nb" / b"bytes"原始字符串 / 字节串前者反斜杠不转义;后者元素是 0–255 的整数
f"{x}"f-string3.6+,见后文格式说明符

数值运算里最容易踩的坑:7 // 2 == 3、-7 // 2 == -4(向下取整),7 % 3 == 1、-7 % 3 == 2(余数符号跟随除数),0.1 + 0.2 == 0.30000000000000004(二进制浮点无法精确表示 0.1)。金额等需要精确十进制的场景改用 decimal.Decimal,见 3.1 数值、字符串与 f-string 格式化 。

运算符优先级

从最低到最高排列,同一行内从左到右结合(** 例外,从右到左):

优先级运算符说明
最低:= / lambda海象赋值 / 匿名函数
↓if–else条件表达式
↓or / and / not x逻辑或、与、非,短路求值
↓in / is / < <= > >= != ==成员、身份与比较,可链式
↓| / ^ / &按位或、异或、与
↓<< / >>移位
↓+ / -加减
↓* / / / // / % / @乘除、整除、取模、矩阵乘
↓+x / -x / ~x一元正负与按位取反
最高**幂,右结合
>>> 2 ** 3 ** 2
512                          # 右结合,等价于 2 ** (3 ** 2)
>>> -2 ** 2
-4                           # 一元负号优先级低于 **
>>> 1 < 2 < 3
True                         # 链式比较等价于 (1 < 2) and (2 < 3)

四大容器:常用方法与复杂度

列表 list(可变、有序、允许重复):

操作复杂度说明
lst[i] / lst[i] = xO(1)按索引读写
lst.append(x) / lst.pop()均摊 O(1)尾部追加 / 弹出
lst.insert(0, x) / lst.pop(0)O(n)头部插入删除要整体挪动
x in lstO(n)线性查找
lst.sort()O(n log n)原地排序,返回 None

元组 tuple:与列表同样支持索引与切片,但不可变,因此可作为字典键、可放进集合。

字典 dict(键值映射,3.7+ 保持插入顺序):

操作复杂度说明
d[k] / d[k] = v平均 O(1)按键读写
d.get(k, default)平均 O(1)键不存在时返回默认值
k in d平均 O(1)判断键是否存在
d.setdefault(k, v)平均 O(1)键存在则取值,否则插入并返回
d.items() / d.keys() / d.values()O(1)返回视图,不复制

集合 set(无序、元素唯一、要求可哈希):

操作复杂度说明
s.add(x) / x in s平均 O(1)增删查
s | t / s & t / s - t / s ^ t平均 O(len)并、交、差、对称差

关键结论:需要「查某元素在不在」时,先把容器换成 dict 或 set,in 从 O(n) 降到平均 O(1)。各容器的选择与底层实现见 3.2 列表、元组、字典与集合 。

切片规则

切片写作 seq[start:stop:step],三个位置都可省略,stop 不包含:

>>> s = "abcdef"
>>> s[1:4], s[:3], s[3:], s[::2], s[::-1]
('bcd', 'abc', 'def', 'ace', 'fedcba')
>>> nums = [0, 1, 2, 3, 4, 5]
>>> nums[1:5:2]
[1, 3]
>>> nums[::-1]
[5, 4, 3, 2, 1, 0]
写法含义
seq[:]浅拷贝整个序列
seq[::-1]反转(返回新对象)
seq[i:j]下标 [i, j) 的片段
负数下标从尾部计数,-1 是最后一个
越界索引不报错,自动截断到边界(但 seq[i] 单点取值会报 IndexError)

推导式

四种容器都有对应的推导式,写法一致:表达式 for 变量 in 可迭代对象 [if 条件]。

>>> [i * i for i in range(5)]
[0, 1, 4, 9, 16]
>>> [i for i in range(10) if i % 2 == 0]
[0, 2, 4, 6, 8]
>>> {c: ord(c) for c in "abc"}
{'a': 97, 'b': 98, 'c': 99}
>>> {c for c in "aabbcc"}
{'a', 'b', 'c'}
>>> list(zip([1, 2, 3], "abc"))
[(1, 'a'), (2, 'b'), (3, 'c')]
  • 列表推导用 [],字典用 {k: v ...},集合用 {...},生成器用 (...)。
  • 生成器表达式是惰性的,不会一次性把结果算出来,适合大序列。
  • 嵌套推导可读性差,超过两层建议改成普通循环。详见 4.1 条件、循环与推导式 。

解包与星号

a, *b, c = [1, 2, 3, 4, 5] 后 b == [2, 3, 4];{**{"x": 1}, "z": 3} 得到 {'x': 1, 'z': 3}。

场景写法作用
解包序列a, b = pair按位置赋值
收集剩余first, *rest = seqrest 恒为列表
合并字典{**d1, **d2}后者覆盖同名键
展开参数f(*args, **kwargs)序列拆成位置参数、字典拆成关键字参数
忽略值_, x = pair下划线是约定俗成的「不要」

函数参数四种形态

def f(a, b=2, *args, c, d=4, **kw):
    return a, b, args, c, d, kw

>>> f(1, 9, 8, 7, c=3, x=5)
(1, 9, (8, 7), 3, 4, {'x': 5})
形态语法说明
位置参数def f(a, b)调用时必须按顺序给出
默认参数def f(a, b=2)有默认值的参数必须排在无默认值之后
可变位置def f(*args)args 是元组,收集多余位置参数
可变关键字def f(**kw)kw 是字典,收集多余关键字参数
仅位置def f(a, /, b)3.8+,/ 之前的只能按位置传
仅关键字def f(*, c)* 之后的只能按关键字传

顺序固定为:位置 → 默认 → *args → 仅关键字 → **kw。默认参数在函数定义时求值一次,因此绝不要用可变对象当默认值(见附录 D)。

def g(a, /, b, *, c):
    return a, b, c

>>> g(1, 2, c=3)
(1, 2, 3)

作用域与 global / nonlocal

Python 按 LEGB 规则查找名字:Local(当前函数)→ Enclosing(外层函数)→ Global(模块)→ Builtin(内置)。

关键字作用使用场景
global x声明 x 指向模块级变量函数内要重新赋值模块变量时
nonlocal x声明 x 指向外层函数的变量闭包内修改外层函数的计数器
counter = 0

def inc():
    global counter
    counter += 1

def outer():
    n = 0
    def inner():
        nonlocal n
        n += 1
        return n
    return inner

>>> inc(); counter
1
>>> h = outer(); h(), h(), h()
(1, 2, 3)

只读取外层变量不需要声明;只有重新赋值(即让名字绑定到新对象)才需要 global / nonlocal。详见 4.2 函数:参数传递、默认值与作用域 。

类与继承

class Animal:
    kind = "animal"                 # 类属性,所有实例共享

    def __init__(self, name):
        self.name = name            # 实例属性

    def speak(self):
        return f"{self.name} makes a sound"

class Dog(Animal):
    def speak(self):                # 覆写父类方法
        return f"{self.name} barks"

>>> Dog("Rex").speak(), Dog.kind, Animal.kind
('Rex barks', 'animal', 'animal')
>>> issubclass(Dog, Animal), isinstance(Dog("Rex"), Animal)
(True, True)
概念写法要点
实例方法def m(self)首个参数是 self
类方法 / 静态方法@classmethod / @staticmethod首个参数分别是 cls / 无
属性@property用访问字段的语法调用方法
继承class B(A)单继承;多继承按 MRO 顺序查找
调用父类super().m()协作式继承的正确写法
数据类@dataclass自动生成 __init__ / __repr__ / __eq__

属性查找顺序由 MRO(方法解析顺序)决定,可用 Cls.__mro__ 查看。类机制与 dataclass 见 6.1 类、实例与属性查找(MRO) 与 6.2 继承、组合与 dataclass 。

异常语法

def parse(v):
    try:
        return int(v)
    except ValueError as e:
        return f"bad: {e}"
    except (TypeError, OverflowError):
        return "wrong type"
    else:
        ...              # 没有异常时执行
    finally:
        ...              # 无论如何都执行,用于释放资源
子句何时执行要点
try始终放可能出错的代码
except E as e抛出匹配的异常可写多个,从上到下匹配
elsetry 未抛异常时放「成功之后」的逻辑
finally无论如何清理资源;其中不要写 return

3.11+ 支持 except* 与 ExceptionGroup,一次处理多个异常;3.14 起 except 可以省略括号(PEP 758)。自定义异常、异常链与 raise ... from 见 7.1 异常层次与 try/except/else/finally 与 7.2 自定义异常、异常链与错误设计 。

match 语句(3.10+)

match 做的是结构化模式匹配,不是简单的值相等:

def describe(v):
    match v:
        case int():
            return "int"
        case str() if v == "a":
            return "str-a"
        case [x, y]:
            return f"pair {x},{y}"
        case {"type": "point", "x": x, "y": y}:
            return f"point {x},{y}"
        case _:
            return "other"

>>> describe(1), describe("a"), describe([1, 2]), describe({"type": "point", "x": 1, "y": 2})
('int', 'str-a', 'pair 1,2', 'point 1,2')
模式写法匹配对象
字面量case 1: / case "a":相等即匹配
捕获case x:匹配任何值并绑定到 x
通配case _:匹配任何值、不绑定
类型case int():类型检查
序列case [a, b]:定长序列解构
映射case {"k": v}:字典含该键
守卫 / 或模式case x if x > 0: / case 1 | 2 | 3:附加条件 / 任一匹配

顺序自上而下,第一个匹配的分支生效,因此具体的模式要写在宽泛的模式前面。

类型注解语法(含 PEP 695)

def greet(name: str, times: int = 1) -> str:
    return (name + " ") * times

x: int | None = None            # 3.10+ 用 | 表示联合
pairs: list[tuple[str, int]] = []

# PEP 695(3.12+):类型别名与泛型用新语法
type Vector = list[float]

def first[T](xs: list[T]) -> T:
    return xs[0]

class Stack[T]:
    def __init__(self) -> None:
        self._items: list[T] = []

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

    def pop(self) -> T:
        return self._items.pop()
写法版本说明
x: int3.6+变量 / 参数 / 返回值注解
int | None3.10+联合类型,替代 Optional[int]
list[int] / dict[str, int]3.9+内置容器可直接下标
type X = ...3.12+显式类型别名(PEP 695)
class C[T]: / def f[T]()3.12+泛型参数写在名字后

注解不参与运行时(3.14 起默认延迟求值),只是给类型检查器看的。类型语法与工具链见 9.1 类型注解语法与 pyright / mypy 与 9.2 泛型、Protocol、TypedDict 与 PEP 695 。

常用内置函数速查

函数作用示例
len(x)长度len("abc") → 3
range(a, b, step)整数序列list(range(0, 5, 2)) → [0, 2, 4]
enumerate(it, start)带下标遍历list(enumerate("ab")) → [(0,'a'),(1,'b')]
zip(a, b)并行遍历list(zip([1,2],"ab"))
sorted(it, key, reverse)返回新排序列表sorted([3,1,2]) → [1,2,3]
reversed(seq)反向迭代器list(reversed([1,2])) → [2,1]
sum(it, start)求和sum([1,2,3]) → 6
min(it, key) / max(it, key)最值max([1,2], key=lambda x: -x) → 1
any(it) / all(it)是否存在真 / 是否全真any([0, ""]) → False
map(f, it) / filter(f, it)逐元素映射 / 按条件过滤list(map(str, [1,2])) → ['1','2']
abs(n) / round(n, d)绝对值 / 四舍五入round(3.14159, 2) → 3.14
isinstance(x, T)类型判断isinstance(1, int) → True
print(*objs, sep, end)打印print(1, 2, sep="-") → 1-2

f-string 格式说明符

格式串写作 {值:[填充][对齐][符号][宽度][,][.精度][类型]}:

写法结果说明
f"{x:.2f}"3.14保留两位小数
f"{x:>8}" / f"{x:<8}" / f"{x:^8}"右 / 左 / 居中宽度对齐
f"{n:#x}"0xff十六进制,带 0x 前缀
f"{n:08b}"00001010二进制,宽度 8 补零
f"{p:.1%}"25.6%百分比
f"{n:,}"1,234,567千分位分隔
f"{x:g}" / f"{x:e}"3 / 1.000000e+10通用格式 / 科学计数法
f"{s!r}"'Ada'用 repr 而非 str
>>> name, score = "Ada", 3.14159
>>> f"{name} got {score:.2f}, hex {255:#x}, pct {0.256:.1%}, comma {1234567:,}"
'Ada got 3.14, hex 0xff, pct 25.6%, comma 1,234,567'

3.14 起还新增了模板字符串 t"..."(PEP 750),用于把插值前的结构保留给下游处理,语法与 f-string 类似但返回 Template 对象。

小结

  • 语法速查的价值在于「定位」而非「理解」:先用表找到写法,再回正文看推导。
  • 数值上记两条:// 向下取整、浮点有精度误差;需要精确十进制时用 decimal。
  • 容器选型只问一句「查得频繁吗」——频繁就把 list 换成 set / dict,in 的复杂度从 O(n) 降到 O(1)。
  • 函数参数记顺序「位置 → 默认 → *args → 仅关键字 → **kw」,并永远不要用可变对象当默认值。
  • 作用域只记一句:只读取外层变量无需声明,重新赋值才需要 global / nonlocal。
  • match 是结构化匹配而非值比较;类型注解不参与运行时。附录 B 会在这份语法表之上,继续整理标准库常用模块。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「python」更多文章

  1. 《Python高级编程》目录
  2. 《Python高级编程》11.3 PEP 流程与版本迁移策略
  3. 《Python高级编程》11.2 嵌入式与自由线程运行时