📄 一句话概括
Python 里能当表达式用的 4 种、只能当语句的 3 种——if/for/赋值本身还是语句;真正的函数式语言里没有【语句】这个东西。
📝 本节和前面几节的关系
A.3 讲不写名字,这一节讲为什么能直接嵌进任何位置——因为它们本身就是一个值。
一、实测:哪些能放赋值右边
能:1 + 2、a if c else b、[i*i for i in range(3)]、(lambda x: x+1)(2)。
不能:if c: x = 1、for i in x: pass、x = 1(都报语法错误)。
所以 Python 只做到一半:三元与推导式是表达式,if/for/赋值还是语句。
二、没有语句意味着什么
整段程序就是一个大表达式——每一层都能被上一层当参数吃进去。 这就是为什么函数式代码能自然组合:没有【只能单独占一行】的东西。 反过来看也有代价:没有语句就少了【先做这个、再做那个】的直白写法。
三、实际怎么用
能写成表达式的地方就别写语句:x = a if c else b 比 if/else 两行更紧。
推导式代替 append 循环:3 条语句变 1 条。
但别硬套:一段有 4 个步骤的流程,写成一条嵌套表达式就是灾难。
四、动手 Demo:特征2:所有表达式都返回值
列 4 种能当表达式的写法、3 种只能当语句的写法。 两种各数几个。
ok = ["1 + 2", "a if c else b", "[i*i for i in range(3)]",
"(lambda x: x + 1)(2)"]
bad = ["if c: x = 1", "for i in x: pass", "x = 1"]
print(len(ok), len(bad)) # 4 3
try:
compile("x = if True: 1", "<s>", "exec")
except SyntaxError as e:
print(type(e).__name__) # SyntaxError
实跑输出:
--------------------------------------------------------------------
特征2:所有表达式都返回值
--------------------------------------------------------------------
【都是表达式】意味着**每一样东西都能放进赋值右边**。实测 Python 里哪些能、哪些不能:
写成赋值右边 结果
-------------------------------------
1 + 2 有值
a if c else b 有值
[i*i for i in range(3)] 有值
(lambda x: x + 1)(2) 有值
if c: x = 1 语法错误
for i in x: pass 语法错误
x = 1 语法错误
能当表达式用的 4 个
只能当语句的 3 个
**Python 只做到一半**:三元写法和推导式是表达式,**`if`/`for`/赋值本身还是语句。**
**真正的函数式语言里没有【语句】这个东西**——**整段程序就是一个大表达式。**
**这就是为什么函数式代码能自然地嵌进任何位置**:它没有【只能单独占一行】的东西。
实测:能当表达式 4 种、只能当语句 3 种,x = if True: 1 直接语法错误。
真正的函数式语言没有【语句】,整段程序就是一个大表达式。
这就是函数式代码能随便嵌进任何位置的根因。
30 秒实验
- 把一段 if/else 赋值改成三元表达式,行数能少几行?
- 再把一段三层嵌套的表达式拆回语句,看看可读性是不是反而更好。
常见误区
- 以为【都是表达式】只是语法糖。它决定了代码能不能被组合。
- 把长流程压成一条表达式。那不是函数式,那叫没法调试。
自测三问(点开对答案)
1. Python 里哪些不能当表达式? —— if、for、赋值语句(放赋值右边直接报语法错误)。 2. 为什么函数式代码能随便嵌? —— 因为它没有语句,每一样东西本身就是一个值。 3. 表达式化的代价? —— 少了先做这个再做那个的直白写法,长流程会变得难读。- ☐ A.5 特征3:将函数作为值进行处理
相关笔记
- 函数式语言的7个特征 — 第 2 条的位置
- 特征3:将函数作为值进行处理 — 下一个特征
- 特征1:使用函数编写程序 — 上一条
- 🧩 面向对象是怎样工作的 · 索引