Python 运算符与表达式
Python 算术、比较、逻辑与身份运算符规则;真值测试、短路求值、链式比较,以及表达式在业务分支中的可靠用法。
#concept
#growing
#dev
#python
#python
[!info] related notes
Python 运算符与表达式
这个概念为什么出现
控制流、推导式、断言与数据清洗都建立在表达式上。若不清楚:
/与//的差别and/or返回操作数本身- 链式比较
a < b < c is与==
就会在价格计算、权限判断与空值处理里埋雷。
[!abstract] 一句话理解 Python 表达式按优先级与结合性求值;逻辑运算短路并返回操作数,比较可链式书写,身份与相等必须分开。
最小可运行示例
先把示例放进业务场景,再看代码:
场景:电商结算计算应付金额与权限门闩
结算服务需要:
- 用整数分做金额,避免 float
- 会员折扣与满减的条件组合
- 权限:既要登录又要未冻结
# checkout_expressions.py
# 业务意图:用清晰表达式计算应付分,并判断是否可下单。
# 教学点:
# - // 与 % 用于整数分;
# - and/or 短路;
# - 链式比较让区间判断更可读。
def payable_cents(price_cents: int, vip: bool, coupon_off: int) -> int:
# 会员 9 折;再减优惠券;最低 0 分。
base = price_cents * 90 // 100 if vip else price_cents
after_coupon = base - coupon_off
return after_coupon if after_coupon > 0 else 0
def can_place_order(logged_in: bool, frozen: bool, age: int) -> bool:
# 必须登录、未冻结,且年龄在 18..120(链式比较)。
return logged_in and (not frozen) and (18 <= age <= 120)
def first_nonempty(*labels: str) -> str:
# or 返回第一个真值操作数,常用于默认展示名。
result = ""
for label in labels:
result = result or label
return result or "anonymous"
def main() -> None:
print("payable:", payable_cents(1000, True, 50))
print("can order:", can_place_order(True, False, 20))
print("display:", first_nonempty("", "", "alice"))
print("div:", 5 / 2, "floor:", 5 // 2, "mod:", 5 % 2)
if __name__ == "__main__":
main()
建议运行:
python checkout_expressions.py
期望输出:
payable: 850
can order: True
display: alice
div: 2.5 floor: 2 mod: 1
结合场景再看三个关注点
- 本例假定价格/优惠券是已校验的非负整分,会员折扣向下取整到分;这是明确的舍入选择,不等同于四舍五入或所有计价规则。
and/or不只返回布尔,可能返回操作数——赋值时要小心类型。- 链式比较的中间表达式只求值一次;前一比较为假就不再求值后一项,不能在含副作用时直接改写成重复访问中间表达式。
核心概念与准确模型
常用类别
| 类别 | 例子 | 备注 |
|---|---|---|
| 算术 | + - * / // % ** | / 真除;// 向下取整除 |
| 比较 | == != < <= > >= | 可链式 |
| 逻辑 | and or not | 短路;and/or 返回操作数 |
| 身份 | is is not | 比身份 |
| 成员 | in not in | 容器/串 |
| 位运算 | & | ^ << >> ~ | 整数位操作 |
短路
a and b:a为假则返回a,否则返回ba or b:a为真则返回a,否则返回b
海象运算符(了解)
:= 在表达式内赋值(3.8+),适合 while (line := f.readline()) 一类,避免滥用降可读性。
边界情况与反直觉行为
- 对整数,// 向负无穷取整,(-5) // 2 == -3;非零余数与除数同号,并满足 a == (a // b) * b + a % b。
- 浮点精确相等并非一律无效;对有数值误差的近似结果,按领域容差用 math.isclose,接近零时尤其要考虑 abs_tol。
- 混合类型比较:在 3.x 中任意对象乱序比较可能直接
TypeError。
常见误区
[!warning] 常见误区:把
and/or当一定返回 bool 错误理解:结果类型总是 True/False。
正确模型:返回决定结果的那个操作数;需要布尔时用bool()或直接用于if。
工程实践
- 复杂条件拆成命名布尔变量。
- 权限判断显式写
not frozen,避免双重否定嵌套。 - 金额、库存用整数运算路径单测钉死。
本节总结
表达式是控制流的燃料。先掌握算术边界、短路与身份/相等,再写分支与循环会稳很多。
自测题
0 or "default"的值是什么?a < b < c在b有副作用的属性访问时如何求值?
参考答案
"default"(0 为假,返回后者)。- 先求值 a 与 b 并比较;为真时才求值 c,再用已得到的 b 比较。b 只求值一次;直接展开为两个属性访问可能改变副作用。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| Expressions reference | 规范 | 运算符与求值 |
| stdtypes – boolean ops | 文档 | and/or 语义 |