Python中的安全解引用

47 投票
8 回答
27538 浏览
提问于 2025-04-16 06:21

Groovy 有一个很不错的操作符,可以安全地访问对象的属性或方法,这样可以避免出现空指针异常(NullPointerExceptions):

variable?.method()

只有当 variable 不是空(null)的时候,method 才会被调用。

在 Python 中有没有类似的方法?还是说我必须写 if variable: variable.method() 这样的代码?

8 个回答

8

我在Groovy中用过这个功能,所以我不想重复其他人提到的那些矛盾之处。

在Groovy中,像这样的语句

if(possiblyNull?.value){
    ...

在Python中是这样做的

try:
    testVar = possiblyNull.value
except:
    testVar = None
if(testVar): 

这个功能在Groovy中确实很酷,能帮助减少语法上的杂乱。有一些其他的语法糖,比如Elvis运算符或者*,但它们在快速解决问题的同时,可能会牺牲代码的可读性(换句话说,它们不太符合Python的风格)。

希望这对你有帮助:-)

15

首先,你的选择取决于当变量无法被引用时,你希望表达式的结果是什么。在这些例子中,我假设结果是None

在Python中,有一种常见的写法可以在某些情况下使用条件表达式:

variable.method() if variable is not None else None

虽然这种需求可能不是很普遍,但在某些情况下,它会很有用,尤其是当引用嵌套在一起时,你可能会想要这样的效果,而这种写法会变得比较繁琐。

a?.b?.c?.d

需要注意的是,支持?.操作符来安全地引用是PEP 505: None-aware operators \| Python.org的主要话题之一。目前的状态是“暂缓”。

关于这个话题的一些讨论可以在这里找到:

19

编辑 2021:

现在有一个新的包,算是一种黑科技,能在Python中实现这个功能。这里是它的仓库:https://github.com/paaksing/nullsafe-python

from nullsafe import undefined, _

value = _(variable).method()
assert value is undefined
assert not value
assert value == None

它也能处理 AttributeErrorKeyError

dic = {}
assert _(dic)["nah"] is undefined
assert _(dic).nah is undefined

被包装的对象类型会保持有效。


  1. 不,没有这样的东西。

  2. 不过,要检查一个变量是否是 None,你不能写 if x:,而是要写 if x is None:。这个区别很重要——x 对于很多值(比如0和空集合)会被判断为 False,而这些值其实是有效的;而 x is None 只有在 x 确实指向 None 时才会返回 True

  3. 根据我的个人经验,这种操作符其实很少需要。是的,None 有时用来表示没有值。但可能是因为习惯用法,很多时候代码会返回空对象,或者抛出异常来表示严重错误,所以我每个月只会遇到两次 AttributeError: 'NoneType' object has no attribute '...'

  4. 我认为这可能是个设计缺陷。null 有两个意思——“忘记初始化”和“没有数据”。第一个是个错误,应该抛出异常。第二种情况通常需要比“就不调用这个方法”更复杂的处理。当我向数据库/ORM请求一个 UserProfile,结果没有找到,返回了 null……我想要默默跳过后面的代码吗?还是说我真的想在“库代码”中抛出一个合适的异常(这样“用户(代码)”就知道这个用户不存在,可以做出反应……或者忽略它),或者在我编写特定功能时给用户显示一个合理的消息(“这个用户不存在,你不能把他加到好友列表”)呢?

撰写回答