>>>PyPathPython 学习站
首页›基础篇›kp-005
基础篇 · Foundations lv.1 入门 kp-005

运算符与表达式

前置知识:kp-003、kp-004

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      # 4

7. 直观类比

== 问"长得一样吗",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. 常见误区

  1. 用 is 比较数值或字符串 —— 小整数有缓存(-5~256)会"碰巧"为 True,换大数就翻车;比大小永远用 ==。
  2. 以为 and/or 返回布尔 —— 它返回操作数;需要布尔时套 bool()。
  3. // 与 % 对负数的心算错误 —— Python 取整向"负无穷"方向:-7 // 2 == -4、-7 % 2 == 1。

10. 自测题

  1. x = "a"; x += "b",x 的 id 变吗?lst = [1]; lst += [2] 呢?为什么不同?
  2. 0 or "b"、0 and "b" 各返回什么?
  3. 为什么判断 None 推荐 is None?
参考答案
  1. 字符串不可变,+= 重建对象、id 变;list 可变,+= 走 __iadd__ 原地扩展、id 不变。
  2. "b";0。or 短路返回第一个真值,and 短路返回第一个假值。
  3. NoneType 单例且惯用法能避免自定义 __eq__ 干扰。

11. 与其他知识点的关系

  • kp-006 控制流:运算符的主要消费场景。
  • kp-019 魔术方法:+ in == 都会派发到对应 dunder。
  • kp-028 深浅拷贝:is/== 语义的延伸。

12. 延伸阅读

  • Python 官方教程 §5:https://docs.python.org/zh-cn/3/tutorial/datastructures.html
  • PEP 572(海象运算符)