Правильный импорт пакетов в дизайне Pythonic Library? - PullRequest
0 голосов
/ 26 мая 2018

У меня есть проект Python, структурированный так:

repo_dir/
----project_package/
--------__init__.py
--------process.py
--------config.py
----tests/
--------test_process.py

__init__.py пуст

config.py выглядит так:

name = 'brian'

USAGE

Я использую библиотеку, запустив python process.py из каталога project/project/ или указав путь к файлу python абсолютно.Я использую Python 2.7 в Amazon EC2 Linux.

Когда process.py выглядит как показано ниже, все работает нормально и process.py печатает brian.

import config
print config.name

Когда process.pyвыглядит как ниже, я получаю ошибку ImportError: No module named project.config.

import project.config
print config.name

Когда process.py выглядит как ниже, я получаю ошибку ImportError: No module named project.Это имеет смысл, так как следует ожидать того же поведения, что и в предыдущем примере.

from project import config
print config.name

Если я добавлю эти строки в process.py, чтобы включить корневой каталог библиотеки в sys.path, все конфигурации выше работают нормально.

import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

МОЯ КОНФУЗИЯ

Многие ресурсы предлагают настроить библиотеки python для импорта модулей с использованием project.module_name, но не похоже, что sys.path добавлениестандарт, и кажется странным, что мне это нужно.Я вижу, что приложение sys.path добавило мой корень библиотеки в качестве пути в sys, но я подумал, что именно это должен был делать __init__.py в корне моей библиотеки.Что дает?Что мне не хватает?Я знаю, что импорт Python создает много головной боли, поэтому я постарался максимально упростить это, чтобы обернуть голову вокруг него.Я схожу с ума, и сегодня пятница перед праздником.Я в замешательстве.Пожалуйста, помогите !!

ВОПРОСЫ

Как мне настроить мои библиотеки?Как я должен импортировать пакеты?Где я должен иметь __init__.py файлы?Нужно ли добавлять корень библиотеки в sys.path в каждом проекте?Почему это так запутанно?

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Я думаю, проблема в том, как вы запускаете свой скрипт.Если вы хотите, чтобы скрипт находился в пакете (внутренней папке project), вы должны запускать его с python -m project.process, а не по имени файла.Затем вы можете сделать абсолютный или явный относительный импорт, чтобы получить config из process.

Абсолютный импорт будет from project import config или import project.config.

Явным относительным импортом будетfrom . import config.

Python 2 также допускает неявный относительный импорт, но это очень плохая ошибка, которую вы никогда не должны использовать.При неявном относительном импорте внутренние модули пакетов могут скрывать модули верхнего уровня.Например, файл project/json.py будет скрывать модуль json стандартной библиотеки от всех других модулей в пакете.Вы можете сказать Python, что хотите запретить неявный относительный импорт, поместив from __future__ import absolute_import в верхней части файла.Это стандартное поведение в Python 3.

0 голосов
/ 26 мая 2018

С вашим проектом все в порядке.Я переименовал каталоги просто для ясности в этом примере, но структура такая же, как у вас:

repo_dir/

    project_package/
        __init__.py
        process.py
        config.py

    # Declare your project in a setup.py file, so that
    # it will be installable, both by users and by you.
    setup.py

Когда у вас есть модуль, который хочет импортировать из другого модуля в том же проекте, лучший подходиспользовать относительный импорт.Например:

# In process.py
from .config import name

...

Работая над кодом в своем устройстве разработчика, выполните свою работу в Python virtualenv и установите pip-проект в «редактируемом» режиме.

# From the root of your repo:
pip install -e .

При таком подходе вам никогда не придется обходиться с sys.path - что почти всегда является неправильным подходом.

...