简体   繁体   English

如何在由诗歌管理的 python 项目中使用与工作目录相关的路径导入模块?

[英]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

PS聚苯乙烯

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM