【问题标题】:My module has __init__.py and still Python can't import it我的模块有 __init__.py 但 Python 仍然无法导入它
【发布时间】:2016-10-10 08:47:40
【问题描述】:

我有一个小的 python 模块

+-- address_book
|   +-- models.py
|   +-- __init__.py 
    +-- test
    |   +-- test_models.py 

当我运行python address_book/test/test_models.py 时出现此错误

Traceback (most recent call last):
  File "address_book/test/test_models.py", line 5, in <module>
    from address_book import models
ImportError: No module named 'address_book'

test_models.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import unittest
from address_book import models
...
...
...
if __name__ == '__main__':
    unittest.main()

【问题讨论】:

  • 你的树很奇怪。 __init__.py 是文件,不是目录,对吧?
  • @S.deMelo 我已经更新了树
  • 您从哪个目录运行测试?您可能会发现 python address_book/test/test_models.pypython test_models.py 不起作用的地方起作用。
  • @Dunes 都不起作用

标签: python


【解决方案1】:

你的文件结构应该是这样的

+-- address_book
|    +-- __init__.py
|    +-- models.py
     +-- test
     |    +-- test_models.py
     |    +-- __init__.py

要使您的代码正常工作,您还必须位于 address_book 上方的目录中。

【讨论】:

    【解决方案2】:

    就像评论中所说的,你的树看起来很奇怪。将测试放在与 address_book 相同的级别。

    要运行测试,您应该使用自动测试发现工具,例如nose 或 pytest(如有疑问,请使用 pytest)。这些工具会自动找到它们正在测试的包,这样您就不必安装它们或以任何方式关心它们在 PATH 中的存在。

    一开始可能听起来像是一种负担,必须学习一个新工具,但它非常简单,从长远来看,pytest 真的很有帮助。

    【讨论】:

    • 其实我正在使用nose,它可以工作,但是如果我想生成测试代码覆盖率coverage run --source python address_book/test/test_models.py它不会工作并给我上面同样的错误。
    • 在使用nose时,我曾经使用coverage plugin--with-coverage标志。 (我知道这并不能真正回答 OP,但它可能会有所帮助。)
    【解决方案3】:

    问题源于python不知道在哪里寻找address_book。您可以通过在启动 python 之前设置PYTHONPATH 环境变量来解决此问题。

    给定以下目录结构:

    base_dir
    +-- address_book
    |   +-- __init__.py 
    |   +-- models.py
        +-- test
        |   +-- test_models.py
    

    那么这将起作用:

    $ env PYTHONPATH=/path/to/base_dir python address_book/test/test_models.py
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s
    
    OK
    

    PYTHONPATH 也可以是相对路径,只要相对路径从当前工作目录指向源目录即可

    为了避免每次都输入env PYTHONPATH=/path/to/base_dir,您可以使用您的shell 适当的语法来设置它。下面我使用 bash 语法设置 PYTHONPATH 环境变量。

    $ cd /path/to/base_dir
    $ export PYTHONPATH=. # the current directory as a relative link
    $ python address_book/test/test_models.py
    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.001s
    
    OK
    

    作为旁注,我会更改您的目录结构,因为将测试保存在与源目录相同的目录树中并不是一个好主意。通常你可能会这样做:

    base_dir
    +-- address_book
    |   +-- __init__.py 
    |   +-- models.py
    +-- test # no __init__, not a module
    |   +-- test_models.py
    

    这使您可以更轻松地打包您的项目,而无需同时包含您的测试。

    【讨论】:

      【解决方案4】:
      There is problem with import of module from parent directory as __main__ lies in child folder
      if you do the folder structure like below your same code for import will work
      
      +----test
           +---test_models.py
           +---__init__.py
           +---address_book
               +---__init__.py
               +---models.py
      

      或者您可以将您的项目路径添加到 PYTHONPATH 变量中,您的相同代码也可以使用

      【讨论】:

        猜你喜欢
        • 2012-02-24
        • 2016-06-14
        • 2013-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-30
        • 2012-11-25
        相关资源
        最近更新 更多