Python运算符优先级应聚焦理解结合性与关键争议区,而非死记17级表格;需警惕and/or混用、**右结合、位运算与比较混淆、lambda及:=低优先级等易错点,多数情况应显式加括号。

Python 运算符优先级不是靠死记,而是靠理解结合性 + 少量关键层级划分就能安全写出无歧义表达式。
为什么不能只背表格?
Python 官方文档的运算符优先级表有 17 级,但实际开发中真正容易出错的只有 5–6 个“争议区”:比如 and/or 和比较运算符混用、** 与一元运算符的位置、位运算符和比较运算符的意外绑定。盲目记忆全部层级反而会掩盖真正该加括号的地方。
更关键的是:优先级只解决“谁先算”,而结合性决定“同级怎么连”。比如 2 ** 3 ** 2 是 (2 ** 3) ** 2 == 64 还是 2 ** (3 ** 2) == 512?答案是后者——因为 ** 是右结合。
-
**右结合:a ** b ** c→a ** (b ** c) - 几乎所有二元运算符(
+、-、*、/、&、|、==等)都是左结合 -
=、+=等赋值运算符也是右结合(支持链式赋值a = b = 1)
必须加括号的 4 类典型场景
这些地方即使优先级明确,也强烈建议显式加括号,否则极易被误读或未来维护者改错:
立即学习“Python免费学习笔记(深入)”;
- 混合使用
and/or与比较:写成(x > 0 and x ,而不是x > 0 and x (and优先于or,但人脑不自动按这分组) -
**和一元运算符紧邻:-(2 ** 3)≠(-2) ** 3;前者是 -8,后者是 -8 在 Python 中碰巧相同,但-2 ** 2实际等于-(2 ** 2) == -4,不是 4 - 位运算与比较混用:
a & b == c实际是a & (b == c),因为==优先级高于&;想表达(a & b) == c必须加括号 - 带切片和调用的链式操作:
obj.method()[i]没问题,但obj[method()]()或obj[method][i]语义模糊,括号能立刻澄清意图
最容易被忽略的 3 个低优先级陷阱
它们排在整张表最下方,但恰恰因为“低”,常被默认当成整体参与逻辑,结果出乎意料:
-
lambda表达式优先级最低:x = lambda: 1 if True else 2是合法的,但f = lambda x: x * 2 if x > 0 else 0中的if/else属于 lambda 主体,不是和外部表达式竞争优先级;而g = lambda x: (x * 2 if x > 0 else 0) + 1才需要括号保证条件表达式先求值 -
or和and之间没有“短路优先级”概念:它们就是简单左结合,a or b and c等价于a or (b and c),不是(a or b) and c;这是唯一一个“逻辑运算符内部还有优先级差”的地方 - 赋值表达式(
:=)优先级比布尔运算还低:if (x := get_value()) and x > 0:合法,但if x := get_value() and x > 0:会先算get_value() and x > 0再赋值——报NameError,因为右边的x还未定义
真正要盯住的不是全部 17 级,而是那几个让代码可读性崩塌的交界点:比较 vs 位运算、幂 vs 符号、逻辑连接词之间的隐式分组、以及所有涉及 := 的上下文。其余时候,用括号代替信任记忆。











