基础篇 · Foundations
lv.1 入门
kp-005
运算符与表达式
1. 一句话定义
表达式 = 计算出值的代码;Python 提供算术、比较、逻辑、成员、身份五类常规运算符,外加链式比较与海象运算符两个特色。
2. 为什么重要
运算符是语法的"原子操作"。其中 is 与 == 的区别、真值测试的规则,是贯穿全语言的判断基础;and/or 返回值的特性则是大量 Pythonic 写法的来源。
3. 前置知识
kp-004(各类型的可变性)。
4. 核心概念
| 类别 | 运算符 | 要点 |
|---|---|---|
| 算术 | + - * / // % ** | / 永远得 float;// 向下取整;** 幂 |
| 比较 | == != < > <= >= | 返回 bool;支持链式 a < b < c |
| 逻辑 | and or not | 返回操作数本身,不是布尔值(短路) |
| 成员 | in / not in | 底层调用容器的 __contains__(kp-019) |
| 身份 | is / is not | 比较 id,不是值 |
| 赋值增强 | += -= ... | 对可变对象多为原地修改 |
| 海象 | :=(3.8+) | 表达式内赋值 |
5. 原理与机制
== vs is:== 调用 __eq__ 比"值是否相等";is 比对象身份。判 None 惯用 x is None——因为 NoneType 只有一个实例,且这能防住自定义了 __eq__ 的对象的坑。
逻辑短路取值:a or b 在 a 为真时直接返回 a,否则返回 b:
python
name = "" or "default" # 'default'
val = settings.get("k") or 0海象运算符:把赋值嵌入表达式,省一次重复求值:
python
if (n := len(data)) > 100:
print(f"太长了:{n} 项")
while (chunk := f.read(1024)):
process(chunk)6. 关键事实(模型/图示)
优先级(由高到低,节选):** → 一元 - → * / // % → + - → 比较 → not → and → or。拿不准就加括号——可读性优先。
python
-2 ** 2 # -4 :幂比一元负号绑定更紧
(-2) ** 2 # 47. 直观类比
== 问"长得一样吗",is 问"是同一个人吗"。双胞胎照片完全相同(== 为真),但 is 为假;身份证号相同才是 is。
8. 实例与案例
python
nums = [3, 1, 4]
print(0 in nums) # False
print(0 <= nums[0] < 10) # True:链式比较
nums += [5] # 原地 extend,id 不变
flag = nums and True # and 短路取值9. 常见误区
- 用
is比较数值或字符串 —— 小整数有缓存(-5~256)会"碰巧"为 True,换大数就翻车;比大小永远用==。 - 以为
and/or返回布尔 —— 它返回操作数;需要布尔时套bool()。 //与%对负数的心算错误 —— Python 取整向"负无穷"方向:-7 // 2 == -4、-7 % 2 == 1。
10. 自测题
x = "a"; x += "b",x 的 id 变吗?lst = [1]; lst += [2]呢?为什么不同?0 or "b"、0 and "b"各返回什么?- 为什么判断
None推荐is None?
参考答案
- 字符串不可变,
+=重建对象、id 变;list 可变,+=走__iadd__原地扩展、id 不变。 "b";0。or 短路返回第一个真值,and 短路返回第一个假值。- NoneType 单例且惯用法能避免自定义
__eq__干扰。
11. 与其他知识点的关系
12. 延伸阅读
- Python 官方教程 §5:https://docs.python.org/zh-cn/3/tutorial/datastructures.html
- PEP 572(海象运算符)