☰
Python 语句的表达式和缩进
2026/10/12 4:09:07 网站建设 项目流程

前言


「语句」和「表达式」是两个容易被中文教程混着讲的概念。它们的界限在 Python 里非常清楚,而且直接影响你能不能写出合法代码:表达式会产生一个值,语句执行一个动作。3 + 4是表达式,x = 3 + 4是语句。把表达式单独写在一行(叫「表达式语句」)虽然合法,但那个值会被直接丢弃——这正是无数初学者写出x + 1却发现x没变的原因。


至于缩进,很多人以为它只是「代码美观」问题。不是。Python 用缩进来划分代码块,缩进是语法的一部分:少一个空格或混用一个制表符,程序就直接报错或在语义上被解析成另一个结构。


本文讲清三件事:语句与表达式怎么区分、一行代码太长时怎么安全地换行、缩进规则到底是怎么被解释器处理的。所有内容以 Python 3 为基准,参照语言参考手册对词法分析与复合语句的定义。


一、表达式与语句的区别



  • 表达式(expression):任何会「算出」一个值的写法。字面量42、名字x、算术a + b、函数调用f()、推导式[i for i in range(3)]都是表达式。

  • 语句(statement):一条完整的执行指令。赋值x = 1、import os、def f():、if ...:、return x都是语句。


关键差别:表达式可以嵌套,语句不可以。你可以写max(1 + 2, 3),但不能在一个表达式里塞一条import语句。


那x = 1到底算什么?Python 里赋值是一条语句(在 3.8 之前连海象运算符都没有)。所以下面这些写法都非法:


# 适用于 Python 3 全版本(以下均为错误示例)

# 错误:赋值是语句,不能当表达式嵌套进函数调用
# print(x = 1)

# 错误:不能用赋值语句当作条件
# if (y = 5) > 3:
# pass

第二段在 C 里能写(if ((y = 5) > 3)),在 Python 里必须写成先赋值再比较。如果确实想「在表达式里完成赋值」,Python 3.8 起提供了赋值表达式(walrus,海象运算符:=):


# 适用于 Python 3.8+
data = [1, 2, 3, 4]
if (n := len(data)) > 3:
print(f"长度为 {n},超过 3")

需要 Python 3.8 及以上;旧版本只能先单独写一行n = len(data)。


表达式语句


把表达式单独写一行,就是「表达式语句」。它合法,但返回值被丢弃,只有副作用有意义:


# 适用于 Python 3 全版本
items = [3, 1, 2]
items.sort() # 表达式语句:副作用是原地排序
print(items) # [1, 2, 3]

# 下面这行没有副作用,等于白写
items is not None # 算出一个 True,然后丢掉
# 想要有用,得赋值或用作条件:ok = items is not None

二、逻辑行与物理行


Python 的解析单位是逻辑行(logical line),它由一个或多个物理行(physical line)拼成。理解这一点是掌握换行规则的前提。


2.1 显式续行:反斜杠


物理行以反斜杠\结尾(且该反斜杠不在字符串或注释里)时,会与下一行拼接成一个逻辑行,反斜杠和换行符都被删掉。


# 适用于 Python 3 全版本
if 1900 < year < 2100 and 1 <= month <= 12 \
and 1 <= day <= 31:
print("日期合法")

注意:反斜杠后面不能跟任何字符(包括空格和注释),否则这行本身就报语法错误。


2.2 隐式续行:括号


更推荐的方式是利用括号、方括号、花括号:只要还在一个未闭合的括号里,就可以自由换行,不需要反斜杠,也不受缩进影响。


# 适用于 Python 3 全版本
total = (
1
+ 2
+ 3
)
print(total) # 6

months = ["Jan", "Feb",
"Mar"] # 缩进随意,不影响语义

这正是「一行太长怎么办」的标准答案:先用括号包起来,而不是死磕反斜杠。


三、缩进:INDENT 与 DEDENT


Python 的缩进不是给排版看的,而是被词法分析器转换成两种记号:INDENT(进入新块)和DEDENT(退出块)。规则(取自语言参考手册)如下:



  1. 先维护一个缩进栈,初始压入0。

  2. 每读到一条逻辑行的行首缩进量,就和栈顶比较:



  • 相等:什么都不做

  • 更大:压栈,产生一个INDENT

  • 更小:弹出所有比它大的值,每弹一个产生一个DEDENT;如果弹出的值里没有正好等于它的,就是缩进错误



  1. 制表符在计算缩进时,会按 8 的倍数展开(从前往右补到一个 8 的倍数)。

  2. 如果一个文件混用空格与制表符、且展开结果使含义变得依赖制表符宽度,会抛出TabError。

  3. 反斜杠续行时,缩进以第一个反斜杠之前的空白为准;括号内隐式续行的缩进则被忽略。


因此,块内第一行要先缩进,DEDENT 必须回到栈上出现过的某个层级。下面这个「缩进错乱」的例子会直接报错:


def perm(l): # 第 1 行
for i in l: # 缩进 4,OK
x = i # 缩进 2,和 4 不对齐 → IndentationError
return x

结论很简单:全文件统一用 4 个空格(PEP 8 的推荐),永远不要混用制表符。这样最省心。


# 适用于 Python 3 全版本
def classify(n):
if n > 0:
return "正数"
elif n < 0:
return "负数"
else:
return "零"

print(classify(-3)) # 负数

实战:一段刻意展示换行与缩进的脚本


下面这段代码把本文要点都用上了,可直接运行(Python 3.8+):


# 适用于 Python 3.8+
# 用括号隐式续行组织一条长表达式,用统一 4 空格缩进组织代码块

def parse_pair(text):
"""把 'key=value' 解析成二元组,格式不合法返回 None。"""
if (sep := text.find("=")) == -1:
return None
key = text[:sep].strip()
value = text[sep + 1:].strip()
if not key: # 键不能为空
return None
return (key, value)


def main():
raw_lines = [
"name = Alice",
"age=30",
" broken without equals ",
"=nokey",
]
result = {}
for line in raw_lines:
pair = parse_pair(line)
if pair is None:
continue
result[pair[0]] = pair[1]

for k, v in result.items():
print(k, "->", v)


if __name__ == "__main__":
main()

预期输出是name -> Alice和age -> 30。其中:=需要 Python 3.8 及以上;3.8 以下请先写sep = text.find("="),再判断if sep == -1。


常见坑点



  1. 把赋值当表达式用


❌print(x = 1)或if (y = 5) > 3:✅ 赋值是语句,先赋值再使用;确需在表达式内赋值用 3.8+ 的:=



  1. 表达式语句算完就丢,还以为是赋值


❌ 单独一行写x + 1,期待x变大 ✅x = x + 1或x += 1



  1. 反斜杠续行后加注释或空格


❌a = 1 + \ # 加号或\后面留了空格 ✅ 反斜杠必须是该物理行最后一个字符,且不加注释;更推荐用括号隐式续行



  1. 缩进混用空格与制表符


❌ 一部分行用 4 空格、一部分用 1 个 Tab ✅ 全文件统一 4 空格;混用会抛TabError



  1. 块内缩进量不统一


❌if下第一行缩进 4、第二行缩进 2 ✅ 同一代码块内所有语句缩进量一致



  1. DEDENT 回到一个从未出现过的层级


❌ 从 8 空格直接退到 2 空格(栈上只有 0/4/8) ✅ 退回到栈上已有的某个层级(如 4)



  1. 把条件表达式的顺序写反


❌label = "未成年" if age >= 18 else "成年"✅label = "成年" if age >= 18 else "未成年"(真值在前,else在后)



  1. 用分号把多条语句塞一行


❌a = 1; b = 2;混在一行图省事 ✅ 一行一条语句,需要组织就把逻辑拆进函数


总结




概念要点



表达式会算出一个值,可嵌套

语句执行动作,不可嵌套进表达式

赋值是语句;3.8+ 才可用:=在表达式中赋值

显式续行行尾\,其后不能有任何字符

隐式续行在未闭合的()/[]/{}内自由换行,推荐使用

缩进语法的一部分,生成 INDENT/DEDENT 记号

制表符按 8 的倍数展开;混用可能抛TabError

推荐缩进每层 4 个空格,全文件统一



把「表达式与语句的界限」「用括号而不是反斜杠换行」「全文件统一 4 空格缩进」这三条养成习惯,绝大多数SyntaxError与IndentationError都会在写下的那一刻避免。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询