PEP8-импорт не в верхней части файла с sys.путь
Задача
PEP8 имеет правило о размещении импорта в верхней части файла:
Импорт всегда помещается в начало файла, сразу после любых комментариев и записей модуля, а также перед глобалами и константами модуля.
Однако в некоторых случаях я мог бы сделать что-то вроде:
import sys
sys.path.insert("..", 0)
import my_module
В этом случае утилита командной строки pep8 помечает мой код:
Импорт уровня модуля E402 не в верхней части файл
Каков наилучший способ достижения соответствия PEP8 модификациям sys.path?
Почему
У меня есть этот код, потому что я следую структуре проекта, приведенной в руководстве автостопщика по Python.
Это руководство предполагает, что у меня есть папка
my_module, отдельная от папки tests, обе из которых находятся в одном каталоге. Если я хочу получить доступ к my_module из tests, я думаю, что мне нужно добавить .. к sys.path 5 ответов:
Часто у меня есть несколько файлов с тестами в подкаталоге
foo/testsмоего проекта, в то время как модули, которые я тестирую, находятся вfoo/src. Чтобы запустить тесты изfoo/testsбез ошибок импорта, я создаю файлfoo/tests/pathmagic.py, который выглядит следующим образом;"""Path hack to make tests work.""" import os import sys bp = os.path.dirname(os.path.realpath('.')).split(os.sep) modpath = os.sep.join(bp + ['src']) sys.path.insert(0, modpath)В каждом тестовом файле я использую
import pathmagic # noqaКак первый импорт. Комментарий "noqa" предотвращает
pycodestyle/pep8от жалоб на неиспользованный импорт.
Если есть только несколько импорта, вы можете просто игнорировать PEP8 на этих
importстроках:import sys sys.path.insert("..", 0) import my_module # noqa
Есть еще один обходной путь.
import sys ... all your other imports... sys.path.insert("..", 0) try: import my_module except: raise
Я только что боролся с подобным вопросом, и я думаю, что нашел немного более приятное решение, чем принятый ответ.
Создайте модуль
pathmagic, который выполняет фактическую sys.манипулирование путями, но внесите изменения в контекстном менеджере :"""Path hack to make tests work.""" import os import sys class context: def __enter__(self): bp = os.path.dirname(os.path.realpath('.')).split(os.sep) modpath = os.sep.join(bp + ['src']) sys.path.insert(0, modpath) def __exit__(self, *args): passЗатем в ваших тестовых файлах (или там, где вам это нужно) вы делаете:
Таким образом, вы не получите никаких жалоб от flake8/pycodestyle, вам не нужны специальные комментарии, и структура, кажется, имеет смысл.import pathmagic with pathmagic.context(): import my_module # ...Для дополнительной аккуратности рассмотрите возможность фактического возврата пути в блоке
__exit__, хотя это может вызвать проблемы с ленивым импортом (если вы поместите код модуля вне контекста), так что, возможно, не стоит беспокоиться.
EDIT : просто увидел гораздо более простой трюк в ответе на другой вопрос: Добавьте
assert pathmagicпод вашим импортом, чтобы избежать комментарияnoqa.
Чтобы соответствовать PEP8, вы должны включить свой путь проекта в путь python для выполнения относительного / абсолютного импорта.
Чтобы сделать это, вы можете посмотреть на этот ответ: постоянно добавлять каталог в PYTHONPATH
Comments