Python 语句梳理

Python 语句梳理

Python 的"语句"(statement)与"表达式"(expression)不同:表达式产生值 (如 1+2),语句执行动作(如赋值、循环、导包)。下面按功能分类梳理。


一、赋值语句

1.1 是什么?

赋值语句把右边的值绑定到左边的名字 或容器元素 上。Python 的赋值不是"给变量赋值",而是给名字绑定对象(引用),这一点决定了它的所有行为。

1.2 各种赋值形式

形式 语法 使用说明 样例 输出
基本赋值 x = v 绑定名字到对象 x = 10 x 为 10
链式赋值 a = b = v 多个名字指向同一对象 a = b = [] a is b → True
多重赋值 a, b = v1, v2 按位置解包 a, b = 1, 2 a=1, b=2
交换 a, b = b, a 无需临时变量 a,b=1,2; a,b=b,a a=2, b=1
星号解包 a, *rest = it 收集剩余为 list a, *r = (1,2,3) a=1, r=[2,3]
增强赋值 x += v 原地或新对象(视类型) x=1; x+=2 3
索引赋值 lst[i] = v 修改容器元素 l=[1]; l[0]=9 [9]
切片赋值 lst[a:b] = it 替换切片(长度可变) l=[1,2,3]; l[1:]=[9]; l [1, 9]
属性赋值 obj.attr = v 修改对象属性 --- ---
海象运算符 (n := expr) 表达式内赋值(Py3.8+) [y for x in [1,2] if (y:=x*2)>2] [4]
注解赋值 x: int = 1 类型提示(不改行为) x: int = 1 1

1.3 增强赋值运算符

运算符 等价于 说明
+= x = x + y 对 list 是原地 extend,对其他不可变类型是新对象
-= *= /= //= %= **= 同上 算术类
&= ` = ^=` `>>=` `<<=` 位运算
@= 矩阵乘(numpy 等) ---

python

复制代码
# 增强赋值对可变对象是原地修改(id 不变)
lst = [1, 2]
before = id(lst)
lst += [3]
print(id(lst) == before)   # True(原地扩展)

# 对不可变对象是新对象
t = (1,)
before = id(t)
t += (2,)
print(id(t) == before)     # False(新元组)

1.4 易错点

易错点 说明 正确做法
a = b = [] a、b 指向同一列表 各自创建:a, b = [], []
+= 与 + 对 list,+= 原地、+ 返回新 视是否共享引用选择
解包数量不符 a, b = (1,2,3) 报错 用 *rest 收集
海象运算符优先级 := 需加括号 (x := 10)
赋值不是表达式 y = (x = 1) 报错 Python 用 := 解决

二、条件语句(if / elif / else)

2.1 是什么?

按条件选择执行分支。Python 用缩进划分代码块,不用花括号。

2.2 常见形式

形式 语法 使用说明 样例 输出
if if c: 条件为真执行 if 1: print("y") y
if-else if c: ... else: ... 二分支 "y" if 1 else "n" 'y'
if-elif-else 多分支,从上到下匹配 if x>90: ... elif x>60: ... --- ---
三元表达式 A if cond else B 表达式级的 if-else x = 1 if c else 2 ---
match-case match x: case ... 模式匹配(Py3.10+) 见下 ---
链式比较 0 < x < 10 数学式比较 0 < 5 < 10 True
逻辑组合 and / or / not 短路求值 True or f() True(不调用 f)

2.3 match-case(Py3.10+)

python

复制代码
def handle(command):
    match command.split():
        case ["go", direction]:
            return f"go {direction}"
        case ["quit"]:
            return "quit"
        case ["look", *objects]:
            return f"look {objects}"
        case _:
            return "unknown"

print(handle("go north"))     # go north
print(handle("quit"))         # quit
print(handle("look cat dog")) # look ['cat', 'dog']
模式 说明 样例
case _: 通配(默认分支) case _: pass
case 1: 字面量匹配 case "quit": ...
case [a, b]: 序列解包匹配 case [x, y]: ...
case {"k": v}: 字典键匹配 case {"type": t}: ...
case Point(x, y): 类模式 匹配类型并解包
case x if x > 0: 守卫条件 case n if n%2==0: ...
`case A() B():` 或模式

2.4 易错点

易错点 说明 正确做法
真值判断 if x: 对 0/""/\[\]/None 都为假 需要"存在"时用 is not None
== 与 is == 比值,is 比身份 判 None/True/False 用 is
漏 else 有未覆盖分支 用 elif/else 兜底
and/or 返回对象 不是强制返回 bool (a and b) 可能返回 a 或 b
match 需 Py3.10+ 低版本不可用 用 if-elif 或 dict 映射

三、循环语句(for / while)

3.1 是什么?

  • for:遍历可迭代对象 (序列、range、dict、生成器等),按元素迭代;

  • while:条件为真时反复执行,适合"次数未知"的循环。

3.2 for 循环

形式 使用说明 样例 输出
for x in it: 遍历元素 for c in "ab": print(c) a b
for i in range(n): 数字范围 for i in range(3): print(i) 0 1 2
for i, x in enumerate(it): 同时取索引 for i,x in enumerate("ab"): print(i,x) 0 a 1 b
for k, v in d.items(): 遍历字典键值 --- ---
for a, b in zip(xs, ys): 并行遍历 for a,b in zip([1,2],[3,4]): print(a,b) 1 3 2 4
for x in reversed(it): 反向遍历 for x in reversed("ab"): print(x) b a
嵌套循环 多层 for 见下 ---
for...else: 循环未 break 则执行 else 见下 ---

python

复制代码
# for-else:用于"找元素,没找到则处理"
def find(lst, target):
    for i, x in enumerate(lst):
        if x == target:
            print(f"found at {i}")
            break
    else:
        print("not found")

find([1, 2, 3], 2)   # found at 1
find([1, 2, 3], 9)   # not found

3.3 while 循环

形式 使用说明 样例 输出
while cond: 条件为真执行 i=0; while i<3: print(i); i+=1 0 1 2
while True: 无限循环,配合 break while True: break ---
while...else: 未 break 则执行 else 见下 ---

python

复制代码
i = 0
while i < 3:
    print(i)
    i += 1
else:
    print("done")      # 循环正常结束才会执行
# 0
# 1
# 2
# done

3.4 循环控制语句

语句 作用 样例 说明
break 立即跳出最内层循环 for x in it: break 常用于搜索
continue 跳过本次进入下一轮 if x%2: continue 跳过奇数次迭代
pass 占位,什么都不做 for x in it: pass 待实现时占位
else 循环未 break 时执行 for...else: 与 if-else 语义不同
return 从函数返回(循环中) return x 终止整个函数
yield 生成器产出(循环中) yield x 暂停并返回值

3.5 易错点

易错点 说明 正确做法
循环中增删元素 for x in lst: lst.remove(x) 会跳元素 用 list 推导或倒序删
for...else 误解 else 在未 break 时执行 牢记语义
while 忘自增 死循环 确保循环变量更新
修改迭代中的 dict for k in d: d[k]=... 可以;增删 key 会报错 用 list(d.items())
需要索引却用 for x in it 无法直接知道位置 用 enumerate
浮点计数 while x != 1.0 可能永不结束 用 </> 比较或用整数计数

python

复制代码
# 遍历中删除元素——正确做法
lst = [1, 2, 3, 4]
lst = [x for x in lst if x % 2]      # 推导式重建
# 或
for i in range(len(lst)-1, -1, -1):
    if lst[i] % 2 == 0:
        del lst[i]

四、推导式(Comprehension)

4.1 是什么?

推导式是用一行表达式从可迭代对象生成新容器的语句,比 for 循环更简洁、通常更快。

4.2 四种推导式

类型 语法 样例 输出
列表推导 [expr for x in it if cond] [x*x for x in range(4)] [0, 1, 4, 9]
字典推导 {k: v for x in it} {x: x*x for x in range(3)} {0: 0, 1: 1, 2: 4}
集合推导 {expr for x in it} {x % 3 for x in range(7)} {0, 1, 2}
生成器表达式 (expr for x in it) sum(x*x for x in range(4)) 14

没有"元组推导式" ,圆括号写的是生成器表达式(惰性求值)。

4.3 常见写法

写法 说明 样例 输出
带条件过滤 if 在末尾 [x for x in range(6) if x%2==0] [0, 2, 4]
带三元变换 if-else 在前面 [x if x>0 else 0 for x in [-1,1]] [0, 1]
双层循环 笛卡尔积 [(x,y) for x in [1,2] for y in "ab"] [(1,'a'),(1,'b'),(2,'a'),(2,'b')]
嵌套展平 遍历二维 [x for row in [[1,2],[3]] for x in row] [1, 2, 3]
条件依赖外层 多条件 [x for x in range(10) if x%2==0 if x>4] [6, 8]
生成器表达式 惰性求值 sum(x for x in range(10)) 45

4.4 易错点

易错点 说明 正确做法
可读性差 多层嵌套推导难懂 超过两层用普通 for
推导式里做副作用 如 [print(x) for x in ...] 用 for 循环
内存 列表推导一次生成全部 大数据用生成器表达式
变量泄漏 推导式内变量不泄漏到外部 无需担心
tuple(...) vs 生成器 (x for x in ...) 是生成器 需要元组用 tuple(x for x in ...)

五、异常处理语句

5.1 是什么?

try / except / else / finally 用于捕获和处理运行时错误,让程序在异常时优雅降级,而不是崩溃。

5.2 完整结构

子句 作用 样例
try 放入可能出错的代码 try: x = 1/0
except E as e 捕获指定异常 except ZeroDivisionError as e: print(e)
except (E1, E2): 捕获多种 except (ValueError, TypeError):
except: / except BaseException: 捕获所有(不推荐) 避免吞掉 KeyboardInterrupt
else try 无异常时执行 else: print("ok")
finally 无论是否异常都执行 用于释放资源
raise 主动抛出异常 raise ValueError("bad")
raise ... from e 异常链 raise RuntimeError() from e
assert cond, msg 断言,失败抛 AssertionError assert x > 0, "x>0"

5.3 用法样例

python

复制代码
def safe_div(a, b):
    try:
        result = a / b
    except ZeroDivisionError as e:
        print(f"除数不能为 0: {e}")
        return None
    except TypeError as e:
        print(f"类型错误: {e}")
        return None
    else:
        print("计算成功")
        return result
    finally:
        print("清理资源")

print(safe_div(10, 2))
# 计算成功
# 清理资源
# 5.0

print(safe_div(10, 0))
# 除数不能为 0: division by zero
# 清理资源
# None

5.4 自定义异常

写法 说明
class MyError(Exception): pass 自定义异常类
raise MyError("msg") 抛出
except MyError: 捕获

python

复制代码
class InsufficientError(Exception):
    def __init__(self, balance, amount):
        self.balance = balance
        self.amount = amount
        super().__init__(f"余额 {balance} 不足以支付 {amount}")

try:
    raise InsufficientError(10, 20)
except InsufficientError as e:
    print(e)    # 余额 10 不足以支付 20

5.5 易错点

易错点 说明 正确做法
裸 except: 吞掉所有异常(含 Ctrl+C) 捕获具体异常
吞异常不记录 except: pass 隐藏问题 至少 logging 或重新 raise
finally 里 return 会覆盖 try/except 的返回值 避免在 finally 中 return
异常顺序 父类在前会先被捕获 子类在前,父类在后
raise 无参数 在 except 内重抛当前异常 raise 重新抛出
用异常做流程控制 性能差、可读性差 优先用条件判断
assert 用于生产 -O 优化会移除 assert 用显式 if + raise

六、with 语句(上下文管理)

6.1 是什么?

with 语句用于自动管理资源 (文件、锁、连接),确保使用后自动释放,即使中途发生异常。

6.2 常见用法

用法 说明 样例
文件操作 自动关闭文件 with open("f.txt") as f: f.read()
线程锁 自动加锁/解锁 with lock: ...
多资源 同时管理多个 with open(a) as f1, open(b) as f2:
事务 数据库事务 with conn.transaction(): ...
临时切换 如 contextlib.suppress with suppress(FileNotFoundError): ...

6.3 自定义上下文管理器

python

复制代码
import time
from contextlib import contextmanager

@contextmanager
def timer():
    start = time.time()
    try:
        yield
    finally:
        print(f"耗时: {time.time() - start:.3f}s")

with timer():
    sum(range(10**6))
# 耗时: 0.012s
方式 说明
class CM: __enter__ / __exit__ 类实现
@contextmanager + yield 函数式实现(更简洁)
contextlib.suppress(E) 忽略指定异常
contextlib.ExitStack 动态管理多个资源

6.4 易错点

易错点 说明 正确做法
忘记 with 文件可能不关闭 一律用 with
__exit__ 返回值 返回 True 会吞掉异常 明确返回 False
yield 前后代码 @contextmanager 中 try/finally 包住 yield 保证清理
嵌套多资源 可一行写多个 with a as x, b as y:

七、函数定义语句

7.1 是什么?

def 定义函数;lambda 定义匿名函数;return 返回值;yield 使函数成为生成器;@装饰器 修改函数行为。

7.2 参数类型

参数类型 语法 使用说明 样例
位置参数 def f(a, b): 按顺序传 f(1, 2)
默认参数 def f(a=1): 可省略;默认值只算一次 def f(x, y=2)
关键字参数 f(a=1, b=2) 按名字传 ---
*args def f(*args): 收集多余位置参数为 tuple f(1,2) → (1,2)
**kwargs def f(**kw): 收集多余关键字为 dict f(a=1) → {'a':1}
仅位置参数 def f(a, /, b): / 前的只能按位置传(Py3.8+) ---
仅关键字参数 def f(a, *, b): * 后的只能按关键字传 f(1, b=2)
参数解包 f(*lst) / f(**d) 调用时展开 f(*[1,2])

python

复制代码
def demo(a, b=2, *args, c=3, **kwargs):
    print(a, b, args, c, kwargs)

demo(1, 4, 5, 6, c=7, x=8)
# 1 4 (5, 6) 7 {'x': 8}

7.3 返回与生成器

语句 说明 样例
return v 返回值,结束函数 return x + 1
return 等价 return None ---
return a, b 返回元组 return 1, 2
yield v 产出值并暂停,函数变生成器 yield x
yield from it 委托给子生成器 yield from range(3)
return in generator 结束生成器(Py3.3+ 可带值作 StopIteration.value) ---

python

复制代码
def gen(n):
    for i in range(n):
        yield i * i

print(list(gen(4)))    # [0, 1, 4, 9]

# 生成器是惰性的,适合大数据流
def read_lines(path):
    with open(path) as f:
        for line in f:
            yield line.strip()

7.4 lambda 与装饰器

写法 说明 样例 输出
lambda args: expr 匿名函数,只能单表达式 (lambda x: x+1)(2) 3
sorted(key=lambda x: ...) 作 key 函数 sorted([3,1], key=lambda x:-x) [3, 1]
@decorator 装饰器语法糖 见下 ---
functools.wraps 保留原函数元信息 装饰器内部使用 ---

python

复制代码
import functools

def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"调用 {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log
def add(a, b):
    return a + b

print(add(1, 2))
# 调用 add
# 3

7.5 易错点

易错点 说明 正确做法
可变默认参数 def f(x=[]) 跨调用共享 用 None 占位
闭包延迟绑定 循环里 lambda 捕获同一变量 用默认参数固定:lambda x=i: x
生成器只能用一次 迭代完就耗尽 需要多次遍历转 list
*args 是 tuple 不是 list 需要 list 时转换
装饰器忘 wraps 丢失 __name__ 等 加 @functools.wraps
装饰器带参数 需要三层函数 见标准写法

八、类定义语句

8.1 是什么?

class 定义类(模板),实例化得到对象。涉及继承、super()、属性、方法、类变量 vs 实例变量。

8.2 常见语法

语法 说明 样例
class A: 定义类 ---
class B(A): 单继承 ---
class C(A, B): 多继承(MRO) ---
__init__ 构造方法 def __init__(self, x): self.x = x
super().__init__() 调用父类构造 推荐写法
@property 属性方法(getter) @property def area(self): ...
@x.setter setter @area.setter def area(self, v): ...
@staticmethod 静态方法 无 self/cls
@classmethod 类方法 第一个参数 cls
__str__ / __repr__ 打印表示 自定义输出
__eq__ / __hash__ 相等与哈希 ---

python

复制代码
class Animal:
    kingdom = "animal"                  # 类变量

    def __init__(self, name):
        self.name = name                # 实例变量

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

    def __repr__(self):
        return f"Animal({self.name!r})"

class Dog(Animal):
    def __init__(self, name, breed):
        super().__init__(name)
        self.breed = breed

    def speak(self):                    # 方法重写
        return f"{self.name} barks"

d = Dog("Rex", "Husky")
print(d.speak())     # Rex barks
print(d)             # Animal('Rex')

8.3 数据类(推荐写法)

python

复制代码
from dataclasses import dataclass, field

@dataclass
class Point:
    x: int
    y: int
    tags: list = field(default_factory=list)

p = Point(1, 2)
print(p)             # Point(x=1, y=2)
print(p == Point(1, 2))   # True

8.4 易错点

易错点 说明 正确做法
类变量当默认值 class A: items=[] 跨实例共享 在 __init__ 中初始化
忘 self 方法定义与调用都需 self 静态方法用 @staticmethod
super() 忘括号 super 是类不是调用 super().__init__()
多重继承顺序 MRO 决定查找顺序 用 A.__mro__ 查看
可变默认参数 同函数坑 field(default_factory=...)
__eq__ 未配 __hash__ 定义为 unhashable 需要可哈希时一起定义

九、模块与导入语句

9.1 是什么?

import 把其他模块的名字引入当前命名空间,实现代码复用和组织。

9.2 导入形式

语法 使用说明 样例
import m 导入整个模块,用 m.x 访问 import math; math.pi
import m as alias 起别名 import numpy as np
from m import x 导入名字 from math import pi
from m import x as y 导入并起别名 from math import pi as PI
from m import * 导入全部(不推荐) 污染命名空间
相对导入 包内导入 from . import sibling
if __name__ == "__main__": 脚本入口判断 见下

python

复制代码
# mymodule.py
def hello():
    print("hi")

if __name__ == "__main__":
    hello()      # 只有直接运行时执行

9.3 易错点

易错点 说明 正确做法
循环导入 A 导 B,B 导 A 延迟导入或重构
from m import * 名字冲突、来源不明 显式导入
导入副作用 导入时执行模块顶层代码 把逻辑放函数/main
路径问题 找不到模块 设置 sys.path 或包结构
别名滥用 可读性差 遵循社区约定(np/pd)

十、其他语句

语句 作用 样例 说明
pass 空语句占位 def f(): pass 语法需要但暂无逻辑
del x 删除名字/元素 del lst[0] 解绑或删元素
global x 声明修改全局变量 global count; count += 1 函数内修改全局
nonlocal x 声明修改外层函数变量 nonlocal n; n += 1 闭包修改外层
assert cond 断言 assert x > 0, "x>0" 生产环境可能被优化掉
yield 生成器产出 yield x 见函数部分
return 函数返回 return x 见函数部分
break/continue 循环控制 见循环部分 ---
raise 抛异常 raise ValueError() 见异常部分
...(Ellipsis) 占位(类型提示、numpy 切片) def f(): ... 常用作 stub
; 一行多语句 a=1; b=2 不推荐,可读性差

python

复制代码
# global vs nonlocal
count = 0

def inc_global():
    global count
    count += 1

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

inc_global()
print(count)        # 1
print(outer())      # 1

十一、语句整体对比速查

分类 关键字 核心用途 高频语句
赋值 = += := 绑定名字 解包、增强赋值、海象
条件 if/elif/else match/case 分支选择 if-elif、三元、match
循环 for/while break/continue else 重复执行 for、enumerate、zip、for-else
推导式 [...] {...} (...) 生成容器 列表/字典推导、生成器表达式
异常 try/except/else/finally raise assert 错误处理 try-except、自定义异常
资源 with 自动释放 文件、锁、@contextmanager
函数 def lambda return yield 复用逻辑 参数、装饰器、生成器
类 class 面向对象 __init__、继承、@property
导入 import from...import 模块组织 别名、入口判断
杂项 pass del global nonlocal 控制作用域 占位、作用域修改

十二、易错点总汇(语句层面)

类别 易错点 正确做法
赋值 a = b = [] 共享 a, b = [], []
赋值 解包数量不符 用 *rest
条件 用 if x: 判断 None if x is None:
条件 用 == 比较 None is / is not
循环 遍历中删元素 推导式重建或倒序删
循环 for-else 语义误解 else 在未 break 时执行
循环 while 忘自增 确保循环变量更新
推导式 副作用/多层嵌套 用普通 for
异常 裸 except: 捕获具体异常
异常 finally 中 return 避免
异常 异常顺序错 子类在前
with 不用 with 管资源 一律用 with
函数 可变默认参数 None 占位
函数 闭包延迟绑定 默认参数固定
类 类变量作默认值 在 __init__ 中初始化
导入 from m import * 显式导入
作用域 函数内改全局忘 global 显式声明

小结

层面 记忆要点
赋值 名字绑定对象;可变对象增强赋值原地改;海象 := 表达式内赋值
条件 缩进即代码块;真值判断注意 None;3.10+ 有 match-case
循环 for 遍历可迭代;while 条件驱动;for-else 未 break 才执行;遍历中别改结构
推导式 一行生成容器;无元组推导;生成器表达式惰性
异常 try-except-else-finally 完整结构;捕获具体异常;finally 必执行
with 资源自动释放;@contextmanager 自定义
函数 参数四类(位置/默认/*args/**kwargs);yield 变生成器;装饰器增强
类 __init__、继承、super()、@property;数据类优先 @dataclass
导入 显式导入优于 *;__main__ 入口判断
其他 pass 占位、del 删除、global/nonlocal 改作用域
相关推荐
m0_738120722 小时前
JWT 安全从入门到实战:六种典型攻击场景解析
前端·网络·python·安全·网络安全
用户298698530142 小时前
Python 实现 HTML 转纯文本:两种场景下的文档模型方案
python·html·api
小小张说故事2 小时前
Python 的赋值为什么不会复制对象?拆开引用、浅拷贝与深拷贝
后端·python
ljt27249606613 小时前
Python笔记(十三)--异常
笔记·python
日日大王学编程3 小时前
开源Agent项目记忆设计决策对比
python·ai·langchain·开源·ai编程
vipxieliang3 小时前
Python 魔法方法:让自定义对象更 Pythonic
python
雨晨源码(同名B站)3 小时前
深度学习毕业设计选题推荐:基于YOLO11的交通标志检测系统设计与实现(Python+Django+Vue3+对接deepseek)
人工智能·python·深度学习·机器学习·django·课程设计
2601_967979123 小时前
python中str函数怎么用?使用方法与注意事项详解
python·使用方法·字符串转换·注意事项·str函数
青少儿编程课堂3 小时前
蓝桥杯青少组图形化+信息素养+电子学会Scratch考级:校园口算闯关解析
c++·python·算法·bfs·信息学竞赛