Python中的安全解引用
Groovy 有一个很不错的操作符,可以安全地访问对象的属性或方法,这样可以避免出现空指针异常(NullPointerExceptions):
variable?.method()
只有当 variable
不是空(null
)的时候,method
才会被调用。
在 Python 中有没有类似的方法?还是说我必须写 if variable: variable.method()
这样的代码?
8 个回答
我在Groovy中用过这个功能,所以我不想重复其他人提到的那些矛盾之处。
在Groovy中,像这样的语句
if(possiblyNull?.value){
...
在Python中是这样做的
try:
testVar = possiblyNull.value
except:
testVar = None
if(testVar):
这个功能在Groovy中确实很酷,能帮助减少语法上的杂乱。有一些其他的语法糖,比如Elvis运算符或者*,但它们在快速解决问题的同时,可能会牺牲代码的可读性(换句话说,它们不太符合Python的风格)。
希望这对你有帮助:-)
首先,你的选择取决于当变量无法被引用时,你希望表达式的结果是什么。在这些例子中,我假设结果是None
。
在Python中,有一种常见的写法可以在某些情况下使用条件表达式:
variable.method() if variable is not None else None
虽然这种需求可能不是很普遍,但在某些情况下,它会很有用,尤其是当引用嵌套在一起时,你可能会想要这样的效果,而这种写法会变得比较繁琐。
a?.b?.c?.d
需要注意的是,支持?.
操作符来安全地引用是PEP 505: None-aware operators \| Python.org的主要话题之一。目前的状态是“暂缓”。
关于这个话题的一些讨论可以在这里找到:
编辑 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
它也能处理 AttributeError
和 KeyError
。
dic = {}
assert _(dic)["nah"] is undefined
assert _(dic).nah is undefined
被包装的对象类型会保持有效。
不,没有这样的东西。
不过,要检查一个变量是否是
None
,你不能写if x:
,而是要写if x is None:
。这个区别很重要——x
对于很多值(比如0和空集合)会被判断为False
,而这些值其实是有效的;而x is None
只有在x
确实指向None
时才会返回True
。根据我的个人经验,这种操作符其实很少需要。是的,
None
有时用来表示没有值。但可能是因为习惯用法,很多时候代码会返回空对象,或者抛出异常来表示严重错误,所以我每个月只会遇到两次AttributeError: 'NoneType' object has no attribute '...'
。我认为这可能是个设计缺陷。
null
有两个意思——“忘记初始化”和“没有数据”。第一个是个错误,应该抛出异常。第二种情况通常需要比“就不调用这个方法”更复杂的处理。当我向数据库/ORM请求一个UserProfile
,结果没有找到,返回了null
……我想要默默跳过后面的代码吗?还是说我真的想在“库代码”中抛出一个合适的异常(这样“用户(代码)”就知道这个用户不存在,可以做出反应……或者忽略它),或者在我编写特定功能时给用户显示一个合理的消息(“这个用户不存在,你不能把他加到好友列表”)呢?