如何将对象从 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.py
和 app
,添加一个 __init__.py
,然后使用 python -m project.app.stuff.main
.
如果这对您不起作用(您提到您不想更改项目结构),您还有其他选择。
您可以将每个安装为自己的包(app
和 tests
)。创建一个 setup.py
/setup.cfg
/pyproject.toml
,将 test_db.py
放入包 tests
中,并将它们 pip 安装为可编辑包 pip install -e .
。这将允许您在没有相对导入的情况下导入(仅 import app
和 import tests.test_db
,与文件无关)。这是我个人会走的路线,并推荐这样做。
否则,如果您只是想快速解决问题,那么还有一个更简单且有难度的解决方案。您可以将 test_db.py
的路径添加到 sys.path
(导入时会针对目标模块探索此列表中的每个路径),这样您就可以从任何地方导入 test_db
。再次强调,这非常 hacky,除了快速完整性检查或非常紧急的补丁之外,我不推荐它。
所以,这是项目结构:
<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.py
和 app
,添加一个 __init__.py
,然后使用 python -m project.app.stuff.main
.
如果这对您不起作用(您提到您不想更改项目结构),您还有其他选择。
您可以将每个安装为自己的包(app
和 tests
)。创建一个 setup.py
/setup.cfg
/pyproject.toml
,将 test_db.py
放入包 tests
中,并将它们 pip 安装为可编辑包 pip install -e .
。这将允许您在没有相对导入的情况下导入(仅 import app
和 import tests.test_db
,与文件无关)。这是我个人会走的路线,并推荐这样做。
否则,如果您只是想快速解决问题,那么还有一个更简单且有难度的解决方案。您可以将 test_db.py
的路径添加到 sys.path
(导入时会针对目标模块探索此列表中的每个路径),这样您就可以从任何地方导入 test_db
。再次强调,这非常 hacky,除了快速完整性检查或非常紧急的补丁之外,我不推荐它。