如何将对象从 main.py(在根目录中)导入到子目录中包含的模块中?

How do I import an object from main.py (in the root directory), into a module contained in a subdirectory?

所以,这是项目结构:

<root directory>
- app 
- - name
- - - module1
- - - module2
- - - module3
- - - - tests.py 
- test_db.py

test_db.py 包含一个名为 client 的对象,我在不同模块的所有 tests.py 文件中都需要它。

我可以简单地将 test_db.file 移动到 app 目录中,但是 test_db.py 需要从 main.py 导入 app,这又在根目录中,并且会导致相同的结果再次发布。

在每个 tests.py 中我需要这样的东西:

from ....test_db import client

但它只是得到:

from ....test_db import client

E ImportError: attempted relative import beyond top-level package

所以,我只是想不出从根目录导入 object/package。

P.S:我知道一个简单的解决方案是稍微更改目录结构,但这是一个大项目,更改结构需要大量工作。所以,理想情况下,我需要一些方法将根目录添加到每个 tests.py 文件内的路径中。像这样:

app/name/module3/tests.py:

import sys

#sys.path.something.. I am not really familiar with how to use this

from ....test_db import client #this should import client from test_db in root instead of throwing error

def test_create_todo():
    pass

如果您想在不使用 sys.path 或自定义 loaders/finders 的情况下进行相对导入,您需要:

  • 您导入的 top-most 目录相对于包含 __init__.py
  • 将所述目录指定为 __main__ 模块路径中的包(即 python -m root.stuff.main

简而言之,这意味着您可以添加一个目录 project 来包含 test_db.pyapp,添加一个 __init__.py,然后使用 python -m project.app.stuff.main.

如果这对您不起作用(您提到您不想更改项目结构),您还有其他选择。

您可以将每个安装为自己的包(apptests)。创建一个 setup.py/setup.cfg/pyproject.toml,将 test_db.py 放入包 tests 中,并将它们 pip 安装为可编辑包 pip install -e .。这将允许您在没有相对导入的情况下导入(仅 import appimport tests.test_db,与文件无关)。这是我个人会走的路线,并推荐这样做。

否则,如果您只是想快速解决问题,那么还有一个更简单且有难度的解决方案。您可以将 test_db.py 的路径添加到 sys.path(导入时会针对目标模块探索此列表中的每个路径),这样您就可以从任何地方导入 test_db。再次强调,这非常 hacky,除了快速完整性检查或非常紧急的补丁之外,我不推荐它。