【问题标题】:trying to make paths work - attempted relative import beyond top-level package试图使路径工作 - 尝试相对导入超出顶级包
【发布时间】:2022-02-22 02:31:15
【问题描述】:

我做不到。

我的结构是:

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 from program_name 给出:

ValueError: attempted relative import beyond top-level package

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

但我希望上述方法能够奏效。

【问题讨论】:

  • 你试过import Process.thefile 吗?我假设您正在尝试从顶级文件夹运行程序
  • @ssm: 它给出了'No module named..'
  • 试试from Process import thefile
  • @ssm: 它仍然没有给出任何命名的模块。
  • 哈哈,对不起,我的错。 from src.Process import thefile 这个应该可以工作...

标签: python pytest


【解决方案1】:

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

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

相对导入要求使用它们的模块是 将自身作为包模块导入。


建议一

当前的 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'

tests/thetest.py

from ..src.Process.thefile import s

print s

ma​​in.py

from program_name.tests.thetest import s

执行ma​​in.py

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

建议二

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

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

附注。相对导入适用于包,而不是模块。

【讨论】:

    【解决方案2】:

    刚刚通过大量谷歌搜索解决了类似的问题。 在不改变现有文件结构的情况下,这里有两种解决方案:

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

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

    【讨论】:

    • 很好的答案!注意:使用解决方案 1)您不必指定 pytest 文件(当您有许多 pytest 文件时特别有用)。你可以简单地做python -m pytest
    【解决方案3】:

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

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

    【讨论】:

    • 它给出了,没有模块命名..另外,如果可能的话,我想避免使用 sys 路径。
    • imp module import imp foo = imp.load_source('module.name', '/path/to/file.py') foo.MyClass() 怎么样
    猜你喜欢
    • 2020-11-03
    • 2017-02-22
    • 2020-04-06
    • 2016-05-12
    • 1970-01-01
    • 2020-03-07
    • 2021-10-03
    相关资源
    最近更新 更多