1

我观察到 Python 3 unittest 的奇怪行为。在功能中的 Testcase 测试testValue一个不存在的模块之后。

import sys
import unittest

class ModuleTest(unittest.TestCase):

    def testValue(self):
        import unknown_module
        result = unknown_module.value

        self.assertEqual(0.0, result)


if __name__ == "__main__":
    print(sys.version)
    unittest.main()

Python2 正确给出了以下输出:

2.7.5 (default, May 15 2013, 22:44:16) [MSC v.1500 64 bit (AMD64)]
E
======================================================================
ERROR: testValue (__main__.ModuleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\bin\WinPython-64bit-2.7.5.1\workspace\unknown_module_test.py", line 7, in testValue
    import unknown_module
ImportError: No module named unknown_module

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (errors=1)

但是 Python 3 在unknown_module.value引用 时会声明一个 AttributeError 。

3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)]
E
======================================================================
ERROR: testValue (__main__.ModuleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "unknown_module_test.py", line 8, in testValue
    result = unknown_module.value
AttributeError: 'module' object has no attribute 'value'

----------------------------------------------------------------------
Ran 1 test in 0.016s

FAILED (errors=1)

为什么不像ImportErrorPython 2 那样抛出 Python 3?

4

1 回答 1

3

您正在导入一个隐式命名空间包。引用Python 3.3 What's New 页面

对不需要 __init__.py 标记文件并且可以自动跨越多个路径段的包目录的本机支持(受命名空间包的各种第三方方法的启发,如 PEP 420 中所述)

PEP 420 隐式命名空间包

如果扫描完成但没有返回模块或包,并且至少记录了一个目录,则创建命名空间包。新的命名空间包:

  • __path__属性设置为在扫描期间找到并记录的路径字符串的可迭代。
  • 没有__file__属性。

命名空间包和常规包非常相似。区别在于:

  • 命名空间包的一部分不必全部来自同一个目录结构,甚至不需要来自同一个加载器。常规包是自包含的:所有部分都位于同一目录层次结构中。
  • 命名空间包没有__file__属性。
  • 命名空间包的__path__属性是字符串的只读迭代,当父路径被修改时会自动更新。
  • 命名空间包没有__init__.py模块。
  • 命名空间包的属性具有不同类型的对象__loader__

从您的目录中删除该unknown_module目录,您sys.path的测试将像在早期 Python 版本中那样失败。

于 2013-08-02T11:29:41.113 回答