Python中的空值模式被低估了吗?
我时不时会看到这样的代码:
foo = Foo()
...
if foo.bar is not None and foo.bar.baz == 42:
shiny_happy(...)
看起来有点不太符合Python的风格。
在Objective-C中,你可以对一个空对象发送消息,结果也会返回空。这我觉得挺方便的。当然,在Python中也可以实现一个空值模式,不过根据我在谷歌上找到的信息,这种做法似乎不太常见。为什么会这样呢?
或者说,让None.whatever返回None,而不是抛出异常,这样做会不会是个坏主意呢?
12 个回答
你能不能用 try 和 except 呢?在 Python 里,有句话叫“请求原谅比请求许可更简单”。
所以:
try:
if foo.bar.baz == 42:
shiny_happy(...)
except AttributeError:
pass #or whatever
或者你也可以这样做,这样就不会把一些你不想忽略的错误给静默掉了:
try:
baz = foo.bar.baz
except AttributeError:
pass # handle error as desired
else:
if baz == 42:
shiny_happy(...)
抱歉,但那段代码是符合Python风格的。大多数人都同意,在Python中,“明确比隐晦更好”。Python是一种比大多数语言更容易阅读的语言,大家不应该通过写难懂的代码来破坏这一点。要让意思非常清楚。
foo = Foo()
...
if foo.bar is not None and foo.bar.baz == 42:
shiny_happy(...)
在这个代码示例中,很明显在这条代码路径上,foo.bar有时是None(空值),而且我们只有在它不是None,并且.baz等于42时才会运行shiny_happy()。这样做让任何人都能很清楚地理解这里发生了什么以及原因。对于某些答案中提到的空值模式或try...except代码就不能这样说了。如果你的语言,比如Objective-C或JavaScript,强制使用空值模式,那还好,但在一种根本不使用这种模式的语言中,这只会造成混淆和难以阅读的代码。在编写Python代码时,就要像Python爱好者那样做。
PEP 336 - 让 None 可调用 提出了一个类似的功能:
None 应该是一个可以被调用的对象,当你用任何参数去调用它时,它不会有任何副作用,并且会返回 None。
这个提议被拒绝的原因很简单,就是“大家认为让 None 被调用时会报错是一种特性。”