【问题标题】:Confused about python imports对python导入感到困惑
【发布时间】:2013-08-20 12:41:06
【问题描述】:

我查看了the Python 2.7.5 documentation。我的真实项目有问题,但在这里创建了一个小型测试项目来简洁地重现该问题。想象一个存储在 ~/Development/Test 中的具有以下布局的包

结构如下:

Test/
    __init__.py
    foo.py
    sub/
        __init__.py
        test_foo.py

并且代码(__init__.py 文件是空的):

foo.py

def bar():
    print("hello world")

test_foo.py

import Test.foo
# also tried from Test import foo

def main():
    foo.bar()

if __name__ == "__main__":
    main()

当尝试从终端运行test_foo.py(即python test_foo.py)时,我得到:

Traceback (most recent call last):
  File "test_foo.py", line 1, in <module>
    import Test.foo
ImportError: No module named Test.foo

我正在尝试从子模块的测试文件中导入包中的主文件(foo.py)(在我的实际项目中,子模块是单元测试代码)。奇怪的是使用Sublime text 2 编辑器和插件python test runner,我可以很好地运行我的个人测试,但我无法构建测试文件。它给了我上述错误。

【问题讨论】:

  • 您的错误信息中有一个错字:import foo,您的文件代码状态为import test.foo
  • @kroolik,那是个错误,应该说:Test.foo,我已经修好了。
  • 您不应该创建和运行放置在模块中的脚本。脚本应始终位于模块之外。
  • @ViktorKerkez,不知道你为什么说“脚本”,但我想将单元测试放在模块之外确实有意义。我习惯于在 C# 中构建事物。我将包视为项目的“解决方案”(在本例中是主包和用于测试的子包)。

标签: python linux package importerror


【解决方案1】:

模块名称区分大小写。使用:

import Test.foo as foo

as foo 是为了让您可以在main 中调用foo.bar。)


您还必须在 PYTHONPATH 中列出 ~/Development

如果使用 Unix 并且您的登录 shell 是 bash,将 ~/Development 添加到 PYTHONPATH 编辑 ~/.profile 以包含

export PYTHONPATH=$PYTHONPATH:$HOME/Development

这里是instructions for Windows


更多调试建议:

地点

import sys
print(sys.path)
import Test
print(Test)
import Test.foo

test_foo.py 的顶部。请发布输出。

【讨论】:

  • 我改变了情况(同​​样的问题)。还使用了as foo 子句,也没有解决问题得到:Traceback (most recent call last): File "test_foo.py", line 1, in &lt;module&gt; import Test.foo as foo ImportError: No module named Test.foo
  • 听起来~/Development 未列在您的 PYTHONPATH 环境变量中。您必须添加该目录,以便 Python 知道在哪里导入 Test
  • 我在 linux 上,并将您的更新答案添加到我的 ~/.profile,但它仍然不起作用,即使在重新加载 bash(即 $ . ~/.profile)之后。但是,当我将 test_foo.py 移到 Test 模块之外(到 ~/Development 中)时,它现在可以工作了(如果我再将它移到 ~/ 一级,它就不行了)。
  • 另外,如果我从 ~/.profile 中删除 PYTHONPATH 代码,我会得到相同的结果,如果在 ~/Development 中运行,但不是 ~/ 或 ~/Development/Test/sub
  • 我在上面添加了一个建议,以便我们可以看到一些调试输出。输出将阐明 (1) ~/Development 是否在您的 PYTHONPATH 中,以及 (2) 是否在您想要的 ~/Development/Test 目录之前导入了名为 Test 的其他模块。
【解决方案2】:

可运行脚本应始终放在模块之外。因此,如果您有一个模块和一个从该模块运行一些代码的脚本,那么结构应该如下所示:

foo/
    __init__.py
    bar.py
your_script.py

your_script.py 中的代码应该是这样的:

from foo.bar import your_func

your_func()

在单元测试的情况下一个好主意(这是自以为是的,每个人都有自己的做事方式)将测试放在模块中,因此结构应该如下所示:

foo/
    __init__.py
    bar.py
    tests/
        test_bar.py

但在这种情况下,您不应该直接运行脚本。您应该使用nose 之类的测试框架之一并运行:

nosetests foo

在您放置 foo 模块的目录中。

或者,如果您使用标准的 unittest 库,请创建一个 TestSuite ,然后运行它:

python -m unittest foo.tests.test_bar

再次在您放置 foo 模块的目录中。

【讨论】:

  • 谢谢维克多。我正在使用nose. 我只是将if __name__ == "__main__": 部分添加到test_foo.py 只是为了重现ImportError,在我的实际测试文件中,这不存在。这是我的第一个主要 python 项目,因此更好地了解如何构建目录、文件和可运行脚本非常有帮助。谢谢。
  • 如果您使用的是nose,那么您创建的布局是正确的,您只需从项目外部运行nosetests 脚本,在您的Test 文件夹所在的同一目录中,然后用nosetests Test 运行它,或者你想测试的任何东西,nose 非常灵活。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
  • 2023-03-17
  • 2019-05-10
  • 1970-01-01
  • 2015-03-21
相关资源
最近更新 更多