【问题标题】:submodule couldn't import parentmodule (python)子模块无法导入父模块(python)
【发布时间】:2017-03-04 15:25:51
【问题描述】:

这些是我的模块的目录:

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 guide to 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
    

我照常开始测试: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: 现在,我将from .file2 import someclass 替换为from file2 import someclass。这会产生任何负面影响吗?

【问题讨论】:

  • test 是您的顶级包。对于相对进口,您不能超出此范围。运行mymodule.test.test_file1 或将mymodule 添加到您的Python 路径。

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


【解决方案1】:

对于模块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

【讨论】:

  • 这些测试运行器是如何工作的?我要写它们吗? (如何?)在哪里存放它们? (我猜,也在测试模块中。)|还有关于here 的事情——这是我正在运行的测试的一部分,不是吗?那么如何通过导入我所在的目录来导入另一个目录呢? (我并没有真正理解最后一条路径,因为除了正常的 django 方法之外,我从未使用过 python 测试。)
  • @Asqiir:unittest 模块就是这样一个跑步者。 setup.py 也可以发现测试,nosepytest 项目也可以。
  • @Asqiir: manage.py test 也使用unittest 作为测试运行器。我认为它确实希望测试存在于包内。
猜你喜欢
  • 1970-01-01
  • 2020-12-06
  • 1970-01-01
  • 1970-01-01
  • 2013-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多