ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Python编写条件分支代码方法

Python编写条件分支代码方法 前言「写条件分支」看起来是最没技术含量的活但代码质量的分水岭恰恰在这里。同一个业务规则有人写出五层嵌套的if有人用三行if/elif加一个字典就清爽收尾。区别不在于聪明而在于是否知道 Python 提供了哪些分支写法、各自适合什么场景。初学者最常见的三个误解是以为and/or返回的是True/False其实返回的是参与运算的操作数本身以为match就是 C 的switch其实没有贯穿、还能匹配结构以及以为x or default是安全的默认值写法当x是0或空字符串时会被错误替换。本文按「从简单到复杂」的顺序讲六种条件分支写法并给出各自该在什么时候用。文中的match语句需要 Python 3.10 及以上其余写法在 Python 3.8 及以上都能跑。一、基础if / elif / else最直接的写法。要点是命中即停所以判断顺序就是优先级顺序。# 适用于 Python 3 全版本def http_status_text(code):if code 200:return OKelif code 301:return Moved Permanentlyelif code 404:return Not Foundelif 500 code 600:return Server Errorelse:return Unknown这里用到了链式比较500 code 600它等价于500 code and code 600但更短也更不易写错。二、条件表达式三元运算符当分支只是为了「二选一取值」时用条件表达式比写四行if/else更清晰# 适用于 Python 3 全版本age 17label 成年 if age 18 else 未成年print(label) # 未成年形式是「真值 if 条件 else 假值」顺序和 C 的条件 ? 真值 : 假值相反这是高频写错点。它适合短表达式嵌套多层会立刻变得难读# 适用于 Python 3 全版本# 不推荐嵌套三元可读性差grade A if s 90 else (B if s 80 else C)多层判断还是回到if/elif/else。三、布尔运算的短路与返回值and和or有短路特性而且返回的是操作数本身a or ba为真就返回a否则返回ba and ba为假就返回a否则返回b# 适用于 Python 3 全版本print(0 or 默认) # 默认print(x or 默认) # xprint(0 and 1 / 0) # 0右侧未求值不会除零print(abc and 42) # 42利用返回值可以写出简短的默认值逻辑但要注意假值判断的陷阱or会把0、、[]也当成「没有值」。如果一个合法值就是0必须改用显式的is None判断# 适用于 Python 3 全版本def with_default(value, default100):# 错误示范value 为 0 时也会被替换# return value or default# 正确只在确实是 None 时才用默认值return default if value is None else valueprint(with_default(0)) # 0print(with_default(None)) # 100四、卫语句提前返回消除嵌套深层嵌套的根因通常是「所有失败情况都往里缩进」。反过来写不合格的输入提前 return把主逻辑留在最外层。# 适用于 Python 3 全版本# 不推荐嵌套三层def price_bad(user, item):if user is not None:if user.is_active:if item.stock 0:return item.priceelse:return -1else:return -2else:return -3# 推荐卫语句提前返回def price_good(user, item):if user is None:return -3if not user.is_active:return -2if item.stock 0:return -1return item.price五、字典分派把「值相等」的分支换成查表当分支条件是「某个值和一批常量逐个比较」时用字典把「动作」或「结果」映射起来比一长串elif更好维护。# 适用于 Python 3 全版本def apply_op(op, a, b):operations {: lambda x, y: x y,-: lambda x, y: x - y,*: lambda x, y: x * y,}func operations.get(op)if func is None:raise ValueError(f不支持的运算符{op})return func(a, b)print(apply_op(*, 6, 7)) # 42注意用.get()而不是operations[op]直接下标在没有该键时会抛KeyError除非这正是你想要的错误。字典分派的前提是分派键是可哈希且可比较的常量不适合范围判断。六、match 语句结构化模式匹配Python 3.10从 Python 3.10 起语言引入了match/casePEP 634。它不是switch的翻版没有贯穿fall-through命中一个case就结束能匹配结构序列、映射、类实例不只是值_是通配符相当于默认分支支持守卫子句case ... if 条件:# 适用于 Python 3.10def describe(command):match command.split():case [go, direction]:return f向 {direction} 前进case [look]:return 你环顾四周case [take, item] if len(item) 3:return f拿起一个较长的物品{item}case [take, item]:return f拿起 {item}case _:return 无法识别的指令print(describe(go north)) # 向 north 前进print(describe(take)) # 无法识别的指令需要在 Python 3.10 以下运行时同一段逻辑只能用if/elif判断len(parts)和各位置的值来手写。实战把六种写法用在一个「评分系统」里# 适用于 Python 3.10from dataclasses import dataclassdataclassclass Submission:author: strscore: int | None None # 3.10 的联合类型写法def grade_of(score):if score is None:return 未评分if score 90:return Aif score 80:return Bif score 60:return Creturn Ddef label(submission):if submission.score is None:return f{submission.author}待评分status 优秀 if submission.score 90 else 已评分return f{submission.author}{grade_of(submission.score)}{status}def main():subs [Submission(Ada, 95),Submission(Bob, 72),Submission(Cy, None),]for s in subs:print(label(s))if __name__ __main__:main()输出依次是AdaA优秀、BobC已评分、Cy待评分。注意int | None这种联合类型写法需要 Python 3.10 及以上在 3.9 里要写typing.Optional[int]3.8 同理。常见坑点与混淆❌if code 200:✅if code 200:Python 3 里用在条件位置是语法错误以为and/or返回布尔值❌ 用x and y的结果去做is True判断 ✅ 它们返回操作数本身a and b得到b不是True用or提供默认值把合法假值也替换掉❌return value or default当value是0//[]时误用默认值 ✅return default if value is None else value把match当switch用❌ 期待case会像 C 那样向下贯穿或以为它只比常量 ✅match无贯穿、能做结构匹配、_是通配符需要 Python 3.10字典分派时直接用下标导致KeyError❌operations[op](a, b)✅ 先func operations.get(op)判空后再调用或明确用 try/except 捕获深层嵌套而不使用卫语句❌ 把失败分支一层层缩进到看不见主逻辑 ✅ 不合格输入提前return主逻辑留在最外层把范围判断写进字典分派❌ 试图用{range(0, 60): D, range(60, 80): C}直接查表 ✅range对象相等比较不是区间匹配范围判断仍用if/elif或专门的区间表条件表达式顺序写反❌label 未成年 if age 18 else 成年✅ 真值在前label 成年 if age 18 else 未成年总结写法适用场景注意事项if/elif/else通用分支、范围判断命中即停顺序即优先级条件表达式二选一取值真值在前勿嵌套多层and/or短路简单默认值、守卫返回操作数假值会误触发卫语句消除深层嵌套失败提前返回字典分派常量到结果的映射用.get()防KeyErrormatch结构匹配3.10无贯穿_为通配符判断该用哪种写法只需要问自己两个问题分支条件是「值相等」还是「范围/结构」值是常量就考虑字典分派是结构就用match是范围就用if/elif。至于嵌套过深先想到卫语句而不是继续往里缩进。
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表