Лучшая практика для обработки пути / исполняемых файлов в скриптах проекта на Python (например, что-то вроде manage.py или fabric в Django) - PullRequest
13 голосов
/ 08 февраля 2012

Я много работаю над разными проектами (я ученый) в довольно стандартизированной структуре каталогов. e.g.:

project
   /analyses/
   /lib
   /doc
   /results
   /bin

Я поместил все свои различные служебные скрипты в / bin /, потому что чистота стоит рядом с благочестием. Тем не менее, я должен жестко кодировать пути (например, ../../x/y/z), а затем мне нужно запускать вещи в ./bin/ или они ломаются.

Я использовал Django, и у него есть /manage.py, который запускает различные django-вещи и автоматически обрабатывает путь. Я также использовал fabric для запуска различных пользовательских функций.

Вопрос: Как мне сделать нечто подобное? и как лучше? Я легко могу написать что-нибудь в /manage.py, чтобы вставить корневой каталог в sys.path и т. Д., Но тогда я бы хотел сделать «./manage.py foo», который запустит /bin/foo.py. Или возможно заставить ткань вызывать исполняемые файлы из определенного каталога?

В основном - я хочу что-то легкое и простое в обслуживании. Я хочу иметь возможность помещать исполняемый скрипт / файл / что угодно в ./bin/ и не иметь дело с проблемами пути или импорта.

Каков наилучший способ сделать это?

Ответы [ 3 ]

5 голосов
/ 08 февраля 2012

Сохранить выполнение в TLD

В общем, старайтесь поддерживать время выполнения на верхнем уровне. Это значительно улучшит ваш импорт.

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

Изменение пути

Другие авторы упоминали PYTHONPATH. Это отличный способ сделать это навсегда в вашей оболочке.

Если вы не хотите / не можете напрямую манипулировать путем к проекту PYTHONPATH, вы можете использовать sys.path, чтобы вырваться из относительного ада импорта.

Использование sys.path.append

sys.path это просто внутренний список. Вы можете добавить к нему, чтобы добавить материал на ваш путь.

Скажите, что я в /bin и есть библиотека markdown в lib/. Вы можете добавить относительные пути с помощью sys.path, чтобы импортировать то, что вы хотите.

import sys
sys.path.append('../lib')
import markdown


print markdown.markdown("""

Hello world!
------------

""")

Слово мудрому: Не сходите с ума от ваших дополнений sys.path. Держите вашу схему простой, чтобы избежать путаницы.

Чрезмерно активный импорт может иногда приводить к случаям, когда модуль python должен импортировать сам себя, и в этот момент выполнение останавливается!

Использование пакетов и __init__.py

Еще один замечательный трюк - создание пакетов Python путем добавления файлов __init__.py. __init__.py загружается раньше любых других модулей в каталоге, так что это отличный способ добавить импорт по всему каталогу. Это делает его идеальным местом для добавления sys.path хакерских атак.

Вам даже не нужно обязательно что-либо добавлять в файл. Достаточно просто сделать touch __init__.py на консоли, чтобы сделать каталог пакетом.

См. Этот пост SO для более конкретного примера.

3 голосов
/ 08 февраля 2012

В сценарии оболочки, который вы используете (не запускаете) в текущей оболочке, вы устанавливаете следующие переменные окружения:

PATH=$PATH:$PROJECTDIR/bin
PYTHONPATH=$PROJECTDIR/lib

Затем вы помещаете модули Python и дерево пакетов в свои проекты ./lib каталог,Python автоматически добавляет переменную окружения PYTHONPATH в sys.path.

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

Я рекомендую очень простые скрипты верхнего уровня, такие как:

#!/usr/bin/python

import sys
import mytool

mytool.main(sys.argv)

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

1 голос
/ 08 февраля 2012

Вы можете легко достичь своих целей, создав мини-пакет, в котором размещен каждый из ваших проектов. Используйте вставить сценарии , чтобы создать простой скелет проекта. И чтобы сделать его исполняемым, просто установите его через setup.py develop. Теперь ваши bin-скрипты просто должны импортировать точку входа в этот пакет и выполнить ее.

...