尝试使路径工作 \- 尝试超越顶级包的相对导入

新手上路,请多包涵

我无法完成这项工作..

我的结构是:

 program_name/

  __init__.py
  setup.py

  src/
    __init__.py

    Process/
        __init__.py
        thefile.py

  tests/
     __init__.py
     thetest.py

测试.py:

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

运行: pytest ./tests/thetest.py 来自 program_name 给出:

ValueError: attempted relative import beyond top-level package

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

但我希望以上内容能够奏效。

原文由 George 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 318
2 个回答

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/Process/ thefile.py :

 s = 'Hello world'

测试/ thetest.py

 from ..src.Process.thefile import s

print s

主要文件

 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

附言。相对导入是针对包的,而不是模块。

原文由 Nabeel Ahmed 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

1个

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

它仅在作为顶级包中的包启动时才受支持。在您的情况下,这是从包含 program_name/ 的目录启动命令行并键入(对于 win 环境)

 python -m program_name.tests.thetest

或者简单地(对许多 pytest 文件有用):

 python -m pytest

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 框架兼容。否则第二个应该总是能解决问题。

参考( 即使使用 init.py 也如何修复“尝试在非包中进行相对导入”

原文由 Yibo 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏