if'语句未能防止AttributeError: 'NoneType'对象没有属性
我有一些用Python(版本2.7)写的代码,这段代码利用了OS X自带的PyObjC绑定,通过NSBundle bundleWithPath:来获取一个程序包的可执行文件路径。
#bundlePath is a string/path to a .app or .kext
mainBundle = Foundation.NSBundle.bundleWithPath_(bundlePath)
if mainBundle:
binaryPath = mainBundle.executablePath()
有个客户反馈说这段代码抛出了一个异常,并给我发来了错误追踪信息:
...
File "utils.py", line 184, in getBinaryFromBundle
binaryPath = mainBundle.executablePath()
AttributeError: 'NoneType' object has no attribute 'executablePath'
不幸的是,我在自己的电脑上无法重现这个问题。NSBundle bundleWithPath:总是返回None或者一个有效的程序包对象,而代码似乎也能正常处理这些返回值。
>>> print Foundation.NSBundle.bundleWithPath_(None)
None
>>> print Foundation.NSBundle.bundleWithPath_("invalid/path")
None
>>> print Foundation.NSBundle.bundleWithPath_("/Applications/Calculator.app/")
NSBundle </Applications/Calculator.app> (not yet loaded)
当然,我可以把这段代码放在一个try/except块里来处理异常,但我想问的是,为什么if语句没有阻止这个异常的发生呢?
更新 1
根据一些建议,我确认了:
1) 缩进是正确的
2) 客户使用的是正确的(最新的)代码
...我还在努力搞清楚这个问题!
1 个回答
1
问题并不是说 bundleWithPath
这个调用返回了意外的结果。正如你所说,None
是一个有效的返回值。
这说明客户端的机器上可能有一个奇怪的 Python 版本,在这个版本中,
if None:
print('hello, strange world')
else:
print('hello, world')
居然会打印出 hello strange world
。
我自己从来没有见过这种情况,但这似乎是你所看到现象的唯一解释。而且有很多不同的 Python 解释器,所以其中一个有点奇怪也不让人意外。
通常检查一个变量是否是 None
的做法是明确地进行检查——这样读起来要清晰得多,我觉得。
if mainBundle is not None:
...
把 NoneType
强制转换为 False
用于布尔表达式,会导致一些奇怪和不清晰的语义,特别是当你的代码可能返回 True
、False
或 None
时。
我知道这并没有回答“为什么”的部分,但我认为这可能是因为一个奇怪的 Python 版本。没有详细的信息关于客户端的电脑,或者至少不知道正在运行的 Python 版本,很难说更多。