Является ли каталог Scripts анти-шаблоном в Python? Если да, то какой правильный способ импорта?

Я всегда создавал каталоги скриптов в каждом проекте, который я построил, потому что они полезны для размещения редко используемых исполняемых скриптов. В Python я всегда ставил __init__.py в свой каталог скриптов, поэтому я могу запускать скрипты в виде пакетов (т.е. python -m scripts.some_scripts) и загружать модули из сестринских каталогов. Исходя из этого, а также googling, я начинаю понимать, что это анти-шаблон.

Тем не менее, учитывая структуру вроде:

project_dir/
    some_modules_dir/
        foo.py
        bar.py
        ...
    scripts/
        some_script.py
        other_script.py
        ...

Какой правильный способ запускать скрипты и как правильно их импортировать из каталога-сестра some_modules_dir? Какие каналы должны содержать __init__.py, а какие нет? Я хочу как можно больше следить за PEP8 и хочу как можно больше упростить запуск сценариев. Если у вас есть директория скриптов вообще неотъемлемо нецелесообразно, что вы, ребята, делаете вместо этого?

Ответы

Ответ 1

Ссылка в вопросе только говорит о запуске скриптов , которые находятся в каталоге пакета, что является потенциальной проблемой, потому что... ну... пакеты не являются скриптами, а скрипты не являются пакетами. Они служат в разных целях и используются по-разному, поэтому, если вы смешиваете их вместе, в какой-то момент будет беспорядок.

Так как сам Python имел каталог Scripts для возрастов, и никто не жалуется, он никоим образом не является анти-шаблоном.

См. Как отделить исполняемые файлы от файлов библиотеки? о том, как мы обрабатывали исполняемые скрипты при моем последнем занятии. Это никогда не вызывало никаких проблем, о которых я знаю.

Ответ 2

Лично, наличие __init__.py в одном скрипте dir немного не работает, но я также могу понять, почему он полезен здесь (и в IDE).

Тем не менее, если они уже запущены как модуль Python, то, возможно, они не являются подлинными сценариями, что бы это ни означало (связанное: у вас есть shebang в этих файлах?). Трудно сказать без контекста, но, возможно, они ближе к инструментальным модулям, образуя часть вашей общей кодовой базы Python.

В этом случае с добавлением __init__.py на уровне проекта (project_dir в вашем примере) вы можете использовать обычный импорт в своих потенциальных сценариях:

from some_modules_dir import foo

означает, что ваш оригинальный python -m scripts.some_script делает абсолютный (извините) смысл...

Ответ 3

Setuptools может автоматически создавать сценарии, если вы дадите ему список точек входа (т.е. main() функции). Если вы уже используете Setuptools, его очень легко включить. Затем вы можете объединить каталог scripts с другими пакетами.

Ответ 4

В целом, если ваш проект Python содержит несколько пакетов, которые являются родными для проекта, то, вероятно, должен быть один пакет верхнего уровня, который все остальные пакеты являются подпакетами (ведь они являются частью одного и того же проекта, поэтому должно быть каким-то объединяющим оправданием для их существования). Поскольку каталог считается пакетом только в том случае, если он имеет __init__.py, другой способ сказать это, что, если у каких-либо двух родственных каталогов в вашем проекте есть __init__.py, то их родитель должен также иметь его. Поэтому, полагая, что у вас есть веские основания иметь пакет "скриптов" и пакет "модулей" непосредственно в корне вашего проекта, который, как вы очень хорошо знаете, может быть вашим корневым каталогом проекта.

Если ваш пакет верхнего уровня не является корнем проекта, обычно считается, что некоторые "свободные" скрипты Python смежны с пакетом верхнего уровня. Вот так:

project_root/
    top_level_package/
        __init__.py
        module.py
        subpackage/
            __init__.py
            anothermodule.py
    adjacent_script.py
    adjacent_script_2.py

"Свободные" скрипты могут импортироваться непосредственно из пакетов и модулей, потому что они находятся в том же каталоге, что и пакет верхнего уровня. Предположение с этой конструкцией состоит в том, что пакет верхнего уровня содержит все "интересный" код вашего проекта (ваш "пункт продажи" или "мясо" вашего проекта, если вы хотите), в то время как "свободные" смежные скрипты действуют только поскольку вход указывает на определенные функциональные возможности, которые вы, возможно, захотите получить из пакета верхнего уровня. Например, у вас может быть смежный script для запуска набора тестов, для установки программного обеспечения или для запуска приложения, если ваш проект является приложением.

Что касается вашего конкретного шаблона, у меня создается впечатление, что вы выделяете "скрипты" из "модулей", потому что сценарии подразумеваются как интерфейс между вами и модулями. Если это только для вас как разработчика, и вы используете "скрипты" нечасто, как вы сказали, вероятно, хорошо придерживаться вашего рецепта, если корневой каталог имеет __init__.py. Если, однако, вы (или кто-то еще) также используете "скрипты" в качестве конечного пользователя или часто используете их, то более безопасно предоставлять script рядом с пакетом верхнего уровня, который связывает функции с вашего "скрипты" в одной команде (или, может быть, несколько, если они предлагают очень разные функции) с подкомандой для каждого "script". Возможно, вы захотите использовать стандартный модуль argparse для этого смежного script. В любом случае, вероятно, было бы более целесообразно называть инструменты "скриптов".

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


Некоторые источники: