[英]How to import module using path related to working directory in a python project that managed by poetry?
I'm using poetry to manage my python project, here's the project:我正在使用诗歌来管理我的 python 项目,这是该项目:
my_project/
├── pyproject.toml
├── module.py
└── scripts/
└── main.py
And I want to know how to import function from module.py
into my_scripts/main.py
correctly.我想知道如何将 function 从
module.py
正确地导入到my_scripts/main.py
中。
My pyproject.toml:我的 pyproject.toml:
[tool.poetry]
name = "my_project"
version = "0.1.0"
description = ""
authors = []
[tool.poetry.dependencies]
python = "^3.11"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
I have tried this:我试过这个:
# In my_scripts/main.py
from module import my_function
And run these commands:并运行这些命令:
poetry install
poetry shell
python my_scripts/main.py
then got this error:然后得到这个错误:
ModuleNotFoundError: No module named 'module'
I also have put a __init__.py
under my_project/
but didn't work out.我还在
my_project/
下放了一个__init__.py
但没有成功。
What made it work for me is to create a folder in your root with the same name of the package in the pyproject.toml
file.对我有用的是在你的根目录中创建一个与 pyproject.toml 文件中的
pyproject.toml
的文件夹。 If you don't do this, poetry will not find your project and will not install it in editable mode.如果你不这样做,poetry 将找不到你的项目,也不会以可编辑模式安装它。
You also need to let Python know that a folder is a package or sub-package by placing an __init__.py
file in it.你还需要让 Python 知道一个文件夹是 package 或子包,方法是在其中放置一个
__init__.py
文件。
my_project/
├─ pyproject.toml
├─ my_project/
├─ __init__.py
├─ module.py
├─ scripts/
├─ __init__.py
├─ main.py
When you initialize the folder you should see that the project is installed.初始化文件夹时,您应该会看到项目已安装。
...> poetry install
Installing dependencies from lock file
Installing the current project: my_project (0.1.0)
Last thing, you need to change the import in main.py
.最后一件事,您需要更改
main.py
中的导入。
# main.py
from my_project.module import my_function
print("my_function imported")
You can now activate the virtual environment (if it's not already active) and run your script.您现在可以激活虚拟环境(如果它尚未激活)并运行您的脚本。
...> poetry shell
Spawning shell within: C:\...\my_project\.venv
...
...> python my_project\scripts\main.py
my_function imported
As @sinoroc pointed out in the comments, it is possible (and preferable according to him) to run the module with python -m my_project.scripts.main
.正如@sinoroc 在评论中指出的那样,可以(并且根据他的说法更可取)使用
python -m my_project.scripts.main
运行模块。
I am new to the topic, but according to this SO answer :我是这个话题的新手,但根据这个 SO answer :
__package__ is set to the immediate parent package in <modulename> [when running python via command line with the
-m
option]__package__ 设置为 <modulename> 中的直接父级 package [当通过带有
-m
选项的命令行运行 python 时]
This means that relative imports like the following magically work.这意味着像下面这样的相对导入神奇地起作用了。
# main.py
from ..module import my_function
# ..module tells python to look in the parent directory for module.py
print("my_function imported")
...> python -m my_project.scripts.main
my_function imported
...> python my_project\scripts\main.py
Traceback (most recent call last):
...
ImportError: attempted relative import with no known parent package
I managed to make it work by adding this line to the pyproject.toml
under the [tool.poetry]
section:我设法通过将此行添加到 [
pyproject.toml
[tool.poetry]
部分下的 pyproject.toml 来使其工作:
[tool.poetry]
# ...other fields
packages = [{ include = "**/*" }]
No __init__.py
is needed.不需要
__init__.py
。 Just run:赶紧跑:
poetry install
poetry shell
python scripts/main.py
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.