python中布尔运算本身几乎不耗时,真正影响性能的是短路逻辑能否跳过昂贵计算;and/or返回操作数本身而非true/false,易因假值导致逻辑错误;应将廉价高失败率判断放左侧、昂贵低失败率操作放右侧。

直接说结论:Python中布尔运算本身几乎不耗时,真正影响性能的是短路逻辑能否帮你跳过昂贵计算——比如数据库查询、文件读取、函数调用。别优化and和or本身,要优化它们包裹的表达式执行顺序。
and/or 的返回值不是 True/False,而是操作数本身
这是多数人写错逻辑分支的根源。例如:
user_role = user and user.role or "guest"
看起来像“有 user 就取 role,否则 fallback”,但若 user.role 是空字符串 "" 或 0,整个表达式会错误地走 or 分支,返回 "guest"。
-
a and b返回b(当a为真值),否则返回a -
a or b返回a(当a为真值),否则返回b - 所谓“真值”包括非空容器、非零数字、非
None、非False;""、[]、0、None都是假值
把高开销操作放在短路右侧,低开销判断放左侧
这是提升性能最直接的做法。比如校验用户权限并触发日志:
if user.is_authenticated and expensive_db_check(user.id):
do_something()
如果 user.is_authenticated 是属性访问(快),而 expensive_db_check() 是网络请求(慢),那绝大多数未登录请求根本不会发起 DB 调用。
- 左侧用 cheap + high-failure-rate 判断(如
obj is not None、len(items) > 0) - 右侧放 expensive + low-failure-rate 操作(如 API 调用、正则匹配、大列表遍历)
- 避免反向写法:
if expensive_db_check(user.id) and user.is_authenticated:—— 即使用户未登录,DB 请求也已发出
混合 and/or 时优先级不等于求值顺序
not > and > or 控制的是分组,但求值永远从左到右。这意味着括号改变的是“哪个子表达式先被整体计算”,而不是“跳过哪边”。
x = False or True and False # 等价于 False or (True and False) → False or False → False y = (False or True) and False # 先算括号 → True and False → False
但注意:短路仍然按左→右发生。在 (a or b) and c 中,若 a 为真,则 b 不执行,但 c 一定执行(因为 and 左侧结果是真值)。
- 不要依赖优先级来“隐藏”副作用;副作用是否执行,只取决于短路路径
- 有副作用的函数(如
print()、logging.info())放在 and/or 右侧时,可能完全不运行 - 调试时可在关键位置加
print()验证是否被短路,比猜更可靠
用条件表达式替代 and/or 模拟三元,除非你明确需要短路副作用
很多人用 a and b or c 替代 b if a else c,但前者在 b 是假值时失效。这不是风格问题,是 bug 温床。
# ❌ 危险:b 可能是 []、0、"",导致意外 fallback role = user and user.roles or ["user"] <h1>✅ 安全:语义清晰,无歧义</h1><p>role = user.roles if user else ["user"] </p>
唯一合理使用 and/or 做分支的场景,是你**依赖短路跳过副作用**,比如:
# 只在 user 存在且 active 时发通知,否则静默跳过
notify_user() if user and user.is_active else None
# 等价但更直白:
if user and user.is_active:
notify_user()
复杂布尔链里混入业务逻辑,最容易漏掉假值语义。真要提速,重点不在怎么写 and,而在让左侧判断足够早、足够廉价地拦住后续动作。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











