试图使路径工作 - 尝试相对导入超出顶级包

时间:2017-03-09 07:30:10

标签: python pytest

我无法做到这一点..

我的结构是:

program_name/

  __init__.py
  setup.py

  src/
    __init__.py

    Process/
        __init__.py
        thefile.py

  tests/
     __init__.py
     thetest.py

thetest.py:

from ..src.Process.thefile.py import sth

正在运行:来自pytest ./tests/thetest.py的{​​{1}}:

program_name

我也尝试了其他方法,但我收到了各种错误。

但我希望以上工作能够发挥作用。

3 个答案:

答案 0 :(得分:8)

ValueError:在非包裹中尝试相对导入

说明您尝试在模块中使用相对导入的状态,即将其用于包,即将其作为包添加__init__.py并从包外的某个文件调用thetest.py 。 直接从解释器运行thetest.py将无效。

  

相对导入需要使用它们的模块   将自己导入为包模块。

建议1

当前tests目录有一个__init__.py文件,但是不允许你将它作为模块运行(通过shell) - 为了使你当前(相对)导入工作,你需要将它导入外部(包)文件/模块 - 让我们创建一个main.py(可以任意命名):

    main.py
    program_name/
      __init__.py
      setup.py
      src/
        __init__.py
        Process/
            __init__.py
            thefile.py
      tests/
         __init__.py
         thetest.py

的src /过程/的 thefile.py

s = 'Hello world'

测试/的 thetest.py

from ..src.Process.thefile import s

print s

<强> main.py

from program_name.tests.thetest import s

执行 main.py

[nahmed@localhost ~]$ python main.py 
Hello world

建议2

按照以下方式执行根目录上方的文件,即program_name/上一级:

[nahmed@localhost ~]$ python -m program_name.tests.thetest
Hell World

<强> P.S 即可。相对导入用于包,而不是模块。

答案 1 :(得分:1)

导入文件时,Python仅搜索当前目录,即运行入口点脚本的目录。 您可以使用 sys.path 包含不同的位置

import sys
sys.path.insert(0, '/path/to/application/app/folder')

import thefile

答案 2 :(得分:1)

通过大量的谷歌搜索解决了类似的问题。 这里有两个解决方案,不需要更改现有的文件结构:

1

从父文件夹from ..src.Process.thefile.py import sth导入模块的方法称为“相对导入”。

仅在从顶级软件包启动时才支持它。在您的情况下,即从包含 program_name/ 的目录启动命令行并输入(对于win环境)

python -m program_name.tests.thetest

2

否则 - 尝试单独运行脚本或从非顶级程序包运行脚本时 -  您可以在运行时手动将目录添加到PYTHONPATH。

import sys
from os import path
sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
from src.Process.thefile import s

首先尝试第一个看看它是否与pytest框架兼容。否则第二个应该总能解决问题。

参考(How to fix "Attempted relative import in non-package" even with __init__.py