if条件先判断变量非None再取值是否符合Pythonic规范?
你写的第一种利用短路求值的写法完全符合Pythonic规范,不存在风格问题;第二种try/except写法也不存在绝对的“更优、更显式”,两种写法分属Python社区两种公认的编码范式,适用场景完全不同,选错了反而会让代码可读性变差、更容易出bug。
两种写法对应的编码范式
Python社区对前置判断和异常捕获的选择,本质是LBYL和EAFP两种风格的取舍,没有绝对的高低之分:
LBYL(Look Before You Leap,跳前先看):也就是你写的第一种短路判断写法,核心思路是在执行可能出错的操作前,先把所有前置条件校验一遍。
这种写法的优势是逻辑直白,所有分支都明明白白写在条件里,不会隐式吞掉异常,非常适合待校验的情况是正常业务分支、出现概率高的场景。比如variable是函数可选参数,默认值就是None,代表“未传值”的正常状态,这时候用if variable is not None and variable > 2:是最优选择,读代码的人一眼就能看懂这里处理了None的情况,没有任何理解成本。
用这种写法唯一要注意的是条件顺序:必须把不会触发异常的判断(比如is not None)放在and前面,依赖短路特性保证后面的判断只有在前一个条件成立时才会执行,写反了会直接抛错。EAFP(Easier to Ask for Forgiveness than Permission,求原谅比求许可容易):也就是你提到的try/except写法,确实是Python官方文档明确推荐的编码风格之一,但它有严格的适用前提:你预期会触发异常的情况是小概率的、非正常的边缘场景。
这种写法的优势是主逻辑非常干净,不会被大量前置判断打断。但用的时候有个绝对不能碰的红线:except块必须精准捕获你预期的特定异常,绝对不能裸写except:或者捕获宽泛的Exception。比如你这里要捕获的只有variable为None时触发的TypeError,就必须明确写except TypeError:,否则会把其他完全意料之外的错误(比如variable是字符串、自定义对象和整数比大小抛出的类型错误)也吞掉,把小bug藏成难以排查的线上问题。
要是None是你业务逻辑里的正常分支,还硬套EAFP写法把正常逻辑放进异常捕获里,反而属于反模式:读代码的人会误以为进入except分支是异常情况,和实际业务逻辑不符,完全谈不上“显式”。
选择参考
不用迷信“异常捕获比条件判断更高级”的刻板印象,按场景选就对了:
- 如果
variable is None是业务上会经常出现的正常状态,直接选第一种短路判断写法,地道、好读、好维护。 - 如果
variable按业务约定本来就绝对不应该是None,出现None就代表上游逻辑出错,要么不要捕获异常直接让它抛出来暴露问题,要么用精准的try/except捕获后抛出带明确信息的业务异常,别写多余的前置判断掩盖问题。
内容的提问来源于stack exchange,提问作者thepatriot

