Python 项目目录的文件夹结构和易于导入

Python folder structure for project directory and easy import

我的团队在 python3 中有一个包含几个小项目的文件夹。其中,我们有一个实用程序文件夹,其中包含多个实用程序功能,在整个项目中都使用这些功能。但是导入的方式很不爽。这是我们使用的结构:

temp_projects
    util
        storage.py
        geometry.py
    project1
        project1.py
    project2
        project2.py

问题是项目中的导入看起来很糟糕:

sys.path.insert(1, os.path.join(sys.path[0], '..'))
import util.geometry

util.geometry.rotate_coordinates(....)

此外,pycharm 和其他工具在理解它和提供补全时遇到困难。

有没有更简洁的方法来做到这一点?

编辑: 所有的项目和实用程序都在进行中并且经常修改,所以我正在寻找尽可能灵活和舒适的东西

我相信正确的路线会和你现在做的完全不同。每个项目应存储在不同的 Git 存储库中,共享模块应添加为 git submodules。一旦这些项目变得更大、更复杂(他们可能会),单独管理它们会更容易。

简而言之

项目结构应该是:

Project_1
  |- utils <submodule>
       |- storage.py
       |- geometry.py
  |- main.py

Project_2
  |- utils <submodule>
       |- storage.py
       |- geometry.py
  |- main.py

使用子模块

### Adding a submodule to an existing git directory
git submodule add <git@github ...> <optional path/to/submodule>

### Pulling latest version from master branch for all submodules
git submodule update --recursive --remote

### Removing submodule from project
# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule

# Remove the submodule directory from the project's .git/modules directory
rm -rf .git/modules/path/to/submodule

# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule

进一步阅读https://git-scm.com/book/en/v2/Git-Tools-Submodules

使用 importlib。

import importlib, importlib.util

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

geometry = module_from_file("geometry", "../temp_projects/utils/geometry.py")

geometry.rotate_coordinates(...)

PYTHONPATH 环境变量可能是一种可行的方法。只需将其设置为项目文件夹位置:

PYTHONPATH=/somepath/temp_projects

您将能够按如下方式使用 util

import util.geometry

util.geometry.rotate_coordinates(....)

这也会被PyCharm自动识别。

其他选项(我在我的项目中使用了这个方法):

假设项目 运行 来自 project1.pyproject2.py 文件。

在这些文件的顶部,您可以添加以下导入和操作:

import sys
import os

sys.path.append(os.path.join(os.getcwd(), os.pardir))

import your_other_modules

your_other_modules.py 将包含以下用于导入实用程序的内容

from utils import storage
from utils import geometry
# or from project2 import project2, etc..

也许这不是最好的方法,但就像多了一个选择。我希望它会对某人有所帮助。

如果您为 util 模块创建一个 setup.py 文件,您可以使用 pip 轻松安装它。它会为你处理一切。安装后即可跨系统导入。

import util

pip 安装

# setup.py is in current folder
sudo -H pip3 install .

或者如果 util 模块本身仍在开发中,您可以使用 -e 可编辑选项安装它。然后它会在您更改代码时自动更新安装。

sudo -H pip3 install -e .

对于项目管理,我建议使用 git 作为@Michael liv。是建议,特别是如果你在团队中工作。

根据 Importing files from different folder 在 util 文件夹中添加 __init__.py 将导致 python 将其视为一个包。您可以做的另一件事是使用 import util.geometry as geometry 然后您可以使用 geometry.rotate_coordinates(...) 这也提高了可读性。