子模块无法导入父模块(python)

时间:2017-03-04 15:25:52

标签: python python-3.x python-import git-submodules

这些是我模块的目录:

mymodule
|-__init__.py
|-file1.py
|-file2.py
|-test
  |-__init__.py
  |-test_file1.py
  |-test_file2.py

test_file1.py包含以下命令:from .. import file1

要运行测试,我(在命令行上)执行了此操作:python3 -m unittest test.test_file1。 (当我为整个test目录运行该命令时,它只是告诉我“一切正常”,但没有找到我的测试。)

答案(当然也在命令行中)是(没有很大一部分堆栈跟踪):

   File "/media/me/my_usb/backup me/myfolder/django projects/django-mymodule/mymodule/test/test_file1.py", line 1, in <module>
    from .. import file1
ValueError: attempted relative import beyond top-level package

该怎么做才能解决这个问题?在多个文件中进行测试的最佳做法是什么?

修改 我按照建议尝试了一些事情,这就是我所做的:

  1. 我改变了测试方向(如 Hitchhikers指南中提到的python 。这就是它现在的样子:

    modulewrapper
    |-mymodule (with the 2 files in it)
    |-... (docs, readME and this stuff)
    |-tests
      |-test_file1.py
      |-test_file2.py
    
  2. 我插入这样的方向后导入mymodule(我在每个测试文件的开头添加了这段代码):

    import sys
    sys.path.insert(0, '../mymodule')
    import file1
    
  3. 我像往常一样开始测试:来自tests目录的python3 -m unittest test_file1。 现在发生的是:(首先是堆栈跟踪的相关部分,然后是我的猜测):

    File "/media/me/my usb/backup me/my folder/django projects/django-mymodule/tests/test_file1.py", line 4, in <module>
        import file1
      File "../mymodule/file1.py", line 4, in <module>
        from .file2 import MyClass1, MyClass2
    SystemError: Parent module '' not loaded, cannot perform relative import
    

    如何处理这个新问题? (或者它和以前一样吗?似乎很难成为改变工作代码以便能够运行测试的最佳实践。)

    Edit2:目前,我jusr已将from .file2 import someclass替换为from file2 import someclass。这会产生任何负面影响吗?

1 个答案:

答案 0 :(得分:2)

对于模块test.test_file1test是您的顶级包。你不能去那些相对进口的东西;您只能访问 test包中的其他模块。

运行python3 -m unittest mymodule.test.test_file1(将您的工作目录设置为mymodule的父目录)或将mymodule添加到Python路径并使用from mymodule import file1

通常,最佳做法是在项目旁边放置一个tests 目录

mymodule
|-__init__.py
|-file1.py
|-file2.py
tests
|-test_file1.py
|-test_file2.py

请注意,没有__init__.py文件,但某些测试运行器(特别是pytest)可能需要一个。

Django项目本身就像大多数其他Python项目一样组织测试(例如,参见clickrequestsflake8)。使用测试运行器来发现测试,例如nose

您需要将mymodule父目录添加到Python路径才能使用此功能,当然,您可能需要添加

import os
import sys
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(here))

到测试文件的顶部,或者将其放入放在测试目录中的utils.py文件中。

另见Structure section of the Hitchhikers Guide to Python