在 Python 中设置我的应用程序路径的正确方法

Proper ways to set the path of my app in Python

我对如何在 Python 中正确创建路径有疑问 (Python 3.x)。

我在 Python 中开发了一个具有以下目录结构的小型抓取应用程序。

root
├── Dockerfile
├── README.md
├── tox.ini 
├── src
│   └── myapp
│       ├── __init__.py
│       ├── do_something.py
│       └── do_something_else.py
└── tests
    ├── __init__.py
    ├──  test_do_something.py
    └──  test_do_something_else.py

当我想 运行 我的代码时,我可以转到 src 目录并使用 python do_something.py 但是,因为 do_something.py 有一个来自 do_something_else.py 的导入语句,它失败了,如:

Traceback (most recent call last):
  File "src/myapp/do_something.py", line 1, in <module>
    from src.myapp.do_something_else import do_it
ModuleNotFoundError: No module named 'src'

所以,我最终决定使用下面的命令来指定python路径: PYTHONPATH=../../ python do_something.py 确保路径可见。

但是,有什么更好的方法来提供路径以便我的应用可以 运行? 我想知道这一点,因为当我通过 tox 运行 pytest 时,我将 运行 命令 tox 的目录将位于根目录,以便 tox 可以看到 tox.ini包裹。如果我这样做,那么我很可能 运行 由于 Python 路径设置不正确而陷入类似的问题。

具体想问的问题有:

  1. 像这样创建我自己的项目时,我应该 运行 我的主要代码在哪里?像 python src/myapp/do_something.py 这样的根?或者,转到 src/myapp 目录并 运行 喜欢 python do_something.py?
  2. 一旦确定了我应该执行我的程序的目录,那么从其他py文件导入模块的正确方法是什么?使用 from src.myapp.do_something_else import do_it 可以吗(这意味着我必须从 src 目录添加路径)?或者,不同的导入方式?
  3. 有什么方法可以让 Python 识别路径?我知道有几种方法可以访问通行证,如下所示:

    一个。写 export PYTHONPATH=<path_of_my_choice>:$PYTHONPATH 使 临时访问的路径,或者在我的 .bashrc 中写入该行以使其永久化(但是当我想通过 ansible 或其他自动化工具自动创建 Python 环境时很难重现)

    b。写入 import sys; sys.path.append(<root>) 以将根作为可访问路径

    c。使用 pytest-pythonpath 包(但这并不是一个通用的答案)

非常感谢您的意见!

我的环境

OS: MacOS and Amazon Linux 2
Python Version: 3.7
Dependency in Python: pytest, tox

我建议使用 setup.py 使之成为 python 包。然后你可以在开发模式下安装它python setup.py develop。这样它将在需要指定 PYTHONPATH 的 python 环境 w/o 中可用。

为了测试,您只需安装包 python setup.py install

希望对您有所帮助。

只需两个简单的步骤即可实现。 Python 专家可以评论这是否是一个好的方法(特别是在本 post 末尾提出的结论性警告)。

我会像下面那样做。

首先,我会在根目录中放置一个“__init__.py”,这样层次结构如下所示。这样 python 会将文件夹视为一个包。

root
├── Dockerfile
├── README.md
├── tox.ini 
├── __init__.py
├── src
│   └── myapp
│       ├── __init__.py
│       ├── do_something.py
│       └── do_something_else.py
└── tests
    ├── __init__.py
    ├──  test_do_something.py
    └──  test_do_something_else.py

然后在 "do_something.py" 中,我会在顶部添加这些行。在第二行中,请输入 "root" 目录的完整路径。

import sys
sys.path += ['/home/SomeUserName/SomeFolderPath/root']
from  src.myapp.do_something_else import do_it

请注意,第二行实质上将通过添加根文件夹路径来修改 sys.path(我想直到解释器退出)。如果这不是你能负担得起的,那我很抱歉。