跳到主要内容

Python or 运算符 —— 完整深入教程


Python or 运算符 —— 完整深入教程

============================================================

目录

  1. 概念与基本语义
  2. Python 真值(truthy / falsy)的完整规则
  3. or 的短路求值(short-circuit evaluation)
  4. or 的返回值规则(核心)
  5. 和 if 的区别
  6. 常见的工程使用模式(核心部分)
  7. 和 and 的对比
  8. 多层 or 链式逻辑
  9. 在自动控制 / 数据清洗中的取值原则
  10. 源码视角:CPython 如何执行 or
  11. 常见坑与防错策略
  12. 总结

============================================================

1. 概念:Python 中 or 的语义

Python 中的 or 是“逻辑或”,作用是:

返回第一个真值(truthy);如果没有真值,则返回最后一个值。

注意:不会把返回结果强制转换为 bool,而是返回某个操作数本身。 操作数本来就是 True / False 时,结果也可能是布尔值。

这一点和一些只把逻辑运算结果当作布尔值使用的写法不太一样,实际使用时要特别注意返回的是操作数本身。

============================================================

2. Python “真值 / 假值”规则

假值(Falsy)包括:

  • False
  • None
  • 0 / 0.0
  • ""(空字符串)
  • [](空列表)
  • {}(空字典)
  • ()(空元组)
  • set()
  • range(0)
  • 自定义对象如果 __bool__() 返回 False,或没有定义 __bool__() 但 __len__() 返回 0

真值(Truthy)包括:

除假值外的所有对象,包括:

  • 任意非空字符串
  • 任意非空容器
  • 任意非零数
  • 对象、实例
  • 函数、类
  • 数据库连接对象
  • float('nan') 在真值判断中为 True,但不等于有效测量值。

Pandas DataFrame / Series 等对象通常不能直接放进 if 或 or 做整体真值判断,会出现“真值不明确”的错误;应按目的使用 .empty、.any()、.all() 或显式比较。

============================================================

3. or 的执行过程 —— 短路求值

表达式:

A or B

执行流程:

  1. 评估 A 的布尔值
  2. 如果 bool(A) 为 True → 返回 A(停止,不评估 B)
  3. 如果 bool(A) 为 False → 返回 B

Python 的 or 是短路逻辑,
对于大型对象、函数调用、IO 操作,能节省很多开销。

============================================================

4. or 的返回值规则(重点中的重点)

永远记住一句话:

or 返回第一个真值操作数;如果都为假,则返回最后一个操作数,不强制转成 bool。

示例:

>>> 0 or 10
10
>>> "" or "hello"
"hello"
>>> [] or [1,2,3]
[1, 2, 3]
>>> "abc" or "xyz"
"abc"

============================================================

5. or 与 if 的区别(非常关键)

你在代码里肯定见过:

(1) 判断真假

if value:
    ...

这里 if 会把 value 转成 bool。

(2) 返回值表达式

result = value or default

这里会返回原值,而不是 bool。

例子:

value = 0
print(value or 100)   # 100
if value:
    print("YES")      # 不执行

============================================================

6. Python 工程中的典型 or 用法

(1) 所有假值都需要回退时

display_name = supplied_name or "未命名"

只有业务上明确把 None、空字符串、0、False 等都视为缺省时,才使用这种写法。它不检查数据质量,也不判断数值是否越界。

(2) 只在 None 时使用默认值

timeout = 30 if user_input is None else user_input

这里保留 0。0 是否允许,应按参数的业务规则判断,不能由 or 悄悄决定。

字典查询同理:

candidate = config.get("port")
port = 5432 if candidate is None else candidate

它只处理缺省,不保证结果是有效端口,仍需单独检查类型和范围。

(3) PLC 数值回退

假设 Data_limited、Data_sj 是已有的数据字典:

candidate = Data_limited.get(name)
safe_value = Data_sj.get(name) if candidate is None else candidate

不能用 Data_limited.get(name) or Data_sj[name] 代替:有效的 0 会被替换,备用字典缺键也可能报错。两边都没有值时,safe_value 仍是 None,应交给明确的缺失值处理分支,而不是直接写入 PLC。

(4) 多级选择

v = A or B or C or D

这是“第一个真值”,不是“第一个非 None 值”或“第一个合格测量值”。要保留 0 / False 时使用显式条件,有数据质量要求时使用对应校验规则。

7. or 与 and 的组合

and 与 or 返回某个操作数本身;not 返回布尔值。

定义:

A and B

返回第一个假值;如果没有假值,返回 B。

例子:

>>> 0 and 5
0
>>> 3 and 5
5
>>> "" and "abc"
""

你可以构造复杂逻辑:

result = (A and B) or C

等价于:

如果 A 和 B 都是真值 → 返回 B,否则返回 C

============================================================

8. 多层 or 链式逻辑

v = A or B or C or D

执行顺序:

  1. 检查 A
  2. 如果 A 假 → 检查 B
  3. 如果 B 假 → 检查 C
  4. 如果 C 假 → 返回 D

典型场景:

  • 配置优先级:环境变量 > 配置文件 > 默认参数
  • 数据容错处理
  • 多级兜底逻辑,但需先明确 0、False、NaN 和缺失值分别如何处理

============================================================

9. 控制系统与数据清洗中的取值逻辑

测量值缺失、非法文本、NaN、无穷值和有效的 0 是不同情况。or 只能判断真假,不能完成这些校验。

(1) 选择第一个有限数值

下面按输入顺序选择可转换的有限数值,并保留 0:

import math

def first_finite_number(values):
    for value in values:
        if value is None or isinstance(value, bool):
            continue
        try:
            number = float(value)
        except (TypeError, ValueError, OverflowError):
            continue
        if math.isfinite(number):
            return number
    return None

target_value = first_finite_number([None, 0.0, 12.5])

该函数将可接受的数字转换为 float,并排除布尔值。用于具体 PLC 字段时,还要按字段类型检查精度、单位、上下限、数据质量和时间有效性;有限值不自动代表业务有效。

(2) 没有可用值时

函数返回 None 表示候选均不合格。调用方应进入已有的缺失值处理分支;不能把缺失值统一改成 0,因为 0 可能是一条真实控制指令。

float(raw_value or 0) 也不是通用容错:非法文本仍会转换失败,NaN 会被保留,而 None 会与真实的 0 混在一起。

(3) PLC 未连接时

在已有循环内部,可以显式判断对象和连接状态:

if plc is None or not plc.get_connected():
    continue

plc is None 检查对象是否缺失,get_connected() 检查客户端报告的状态;不能将 not plc 等同于 plc is None。后续通信仍可能失败,应由实际读写操作的异常处理负责。

10. CPython 字节码观察(进阶)

or 的短路语义最终会体现在 CPython 生成的跳转字节码中。不过具体操作码会随 Python 版本变化,不要把某一个版本的 JUMP_IF_TRUE_OR_POP 当成永久固定实现。

可以直接用 dis 查看当前 Python 版本实际生成的字节码:

import dis

dis.dis("A or B")

理解语义时记住“左值为真就跳过右侧求值,左值为假才继续计算右侧”即可;底层操作码名称属于实现细节。

============================================================

11. 常见坑与防错

(1) 错误以为 or 返回 True/False

result = 3 or 5
print(result)  # 3

(2) 使用 0 时注意:

0 or 10  # 10

但在控制系统里 0 可能是合法值(如风门全关)。
这时应该写:

safe_value = (value if value is not None else default)

(3) 空字符串 “” 也是假值

如果用户合法输入了 “” 会被覆盖:

db_user = env_user or ""

(4) NaN 的特殊性

float('nan') 布尔值为 True,但是比较不等于自己:

bool(float('nan'))   # True
float('nan') == float('nan')  # False

============================================================

12. 总结(最简版)

核心三句话:

  1. A or B 返回第一个真值,没有真值返回 B。
  2. or 不强制把结果转成 bool;0 / False 也可能是业务有效值,不能盲目回退。
  3. or 最大的价值是“兜底/默认值/短路”逻辑。

文章作者: 0xdadream
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 0xdadream !
赏
评论

评论将在接近此处时加载,也可点击立即加载。

  目录