Python中的空值模式被低估了吗?

19 投票
12 回答
6241 浏览
提问于 2025-04-15 17:42

我时不时会看到这样的代码:

foo = Foo()
...
if foo.bar is not None and foo.bar.baz == 42:
   shiny_happy(...)

看起来有点不太符合Python的风格。

在Objective-C中,你可以对一个空对象发送消息,结果也会返回空。这我觉得挺方便的。当然,在Python中也可以实现一个空值模式,不过根据我在谷歌上找到的信息,这种做法似乎不太常见。为什么会这样呢?

或者说,让None.whatever返回None,而不是抛出异常,这样做会不会是个坏主意呢?

12 个回答

13

你能不能用 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(...)
14

抱歉,但那段代码是符合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爱好者那样做。

20

PEP 336 - 让 None 可调用 提出了一个类似的功能:

None 应该是一个可以被调用的对象,当你用任何参数去调用它时,它不会有任何副作用,并且会返回 None。

这个提议被拒绝的原因很简单,就是“大家认为让 None 被调用时会报错是一种特性。”

撰写回答