Структура папок Python для каталога проекта и простой импорт

моя команда папку несколько небольших проектов в питон3. Среди них у нас есть служебная папка с несколькими служебными функциями, которые используются во всех проектах. Но способ его импорта очень неудобен. Это структура, которую мы используем:

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 и другие инструменты испытывают проблемы с пониманием его и завершением поставки.

есть более аккуратный способ сделать это?

изменить: Все проекты и utils очень много работают и часто модифицируются, поэтому я ищу что-то как можно более гибкое и удобное

6 ответов


PYTHONPATH переменной окружения может быть способом пойти. Просто установите его в папку "проекты":

PYTHONPATH=/somepath/temp_projects

и вы сможете использовать util следующим образом:

import util.geometry

util.geometry.rotate_coordinates(....)

также это будет распознано PyCharm автоматически.


Я считаю, что правильный маршрут будет полностью отличаться от того, что вы делаете прямо сейчас. Каждый проект должен храниться в другом репозитории Git, модули share должны быть добавлены как 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(...)

другой вариант (я использовал это приложение в своем проекте):

предположим, что проекты выполняются из project1.py и project2.py файлы соответственно.

в верхней части этих файлов вы можете добавить следующие импорт и действия:

import sys
import os

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

import your_other_modules

your_other_modules.py будет содержит следующие утилиты для impotring

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

может быть это не лучший способ, но как еще один вариант. Надеюсь, это кому-то поможет.


при создании для util модуль вы можете установить его просто с помощью pip. Он все сделает за тебя. После установки вы можете импортировать его в систему.

import util

pip install

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

и если util сам модуль все еще находится в разработке, вы можете установить его с помощью -e редактируемый параметр. Затем он автоматически обновляет установку при внесении изменений в код.

sudo -H pip3 install -e .

для администрирования проекта рекомендую использовать git как @Michael liv. предлагает, особенно если вы работаете в команде.


По данным импорт файлов из разных папок добавлять __init__.py в папке util заставит python рассматривать его как пакет. Еще одна вещь вы можете сделать, это использовать import util.geometry as geometry и тогда вы можете использовать geometry.rotate_coordinates(...) что также улучшает читаемость.