'if'语句,不保护AttributeError:'NoneType'对象没有属性

时间:2014-07-19 01:04:37

标签: python objective-c macos pyobjc

我有一些python(v2.7)代码,它使用在PyObjC绑定中构建的OS X来通过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或一个有效的bundle对象,代码似乎按预期处理它。

>>> 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 个答案:

答案 0 :(得分:1)

问题不在于bundleWithPath调用正在返回意外情况。正如您所说,None是它的有效返回值。

这表明客户端的机器有一个奇怪的python版本,其中

if None:
    print('hello, strange world')
else:
    print('hello, world')

实际上会打印hello strange world

我自己从来没有见过这个,但它是你所看到的唯一解释,而且有一大堆不同的蟒蛇口译员,所以对我来说并不令人震惊他们有点奇怪。

检查变量是否为None的普遍接受的做法无论如何都要明确地这样做 - 恕我直接阅读更清楚了,恕我直言。

if mainBundle is not None:
    ...

对布尔表达式强制NoneTypeFalse的整个做法导致一些奇怪和不清晰的语义,特别是当你的代码可以生成TrueFalse时,或None


我知道这并没有回答&#34;为什么&#34;问题的一部分,但我将它变成一个奇怪的python版本。如果没有关于客户端计算机的详细信息,或者至少知道正在运行的python版本,很难说更多。