Автоматический вызов общего кода инициализации без создания файла __init__.py - PullRequest
4 голосов
/ 31 августа 2011

У меня есть два каталога в моем проекте:

project/
  src/
  scripts/

«src» содержит мой отлаженный код, а «scripts» содержит одноразовые скрипты Python.

Я бы хотел, чтобы все сценарии добавили "../src" в свой sys.path, чтобы они могли обращаться к модулям в дереве "src".Один из способов сделать это - написать файл scripts / __ init__.py с содержимым:

scripts/__init__.py:
  import sys
  sys.path.append("../src")

Это работает, но имеет нежелательный побочный эффект - все мои скрипты помещаются в пакет под названием "скрипты».Есть ли другой способ заставить все мои скрипты автоматически вызывать вышеуказанный код инициализации?

Я мог бы просто отредактировать переменную окружения PYTHONPATH в моем .bashrc, но я хочу, чтобы мои скрипты работали "из коробки", не требуя от пользователя возиться с PYTHONPATH.Кроме того, мне не нравится вносить изменения в рамках всего аккаунта только для того, чтобы приспособиться к этому одному проекту.

Ответы [ 3 ]

3 голосов
/ 31 августа 2011

Даже если у вас есть другие планы распространения, возможно, стоит собрать базовую setup.py в вашей папке src.Таким образом, вы можете запустить setup.py develop, чтобы distutils поместил ссылку на ваш код в путь по умолчанию (то есть любые сделанные вами изменения будут отражены на месте без «переустановки» и всех модулей).будет "просто работать", независимо от того, где ваши сценарии).Это будет одноразовый шаг, но это все же еще один шаг больше нуля, так что это зависит от того, будет ли это больше проблем, чем обновление .bashrcЕсли вы используете pip , эквивалент будет pip install -e /path/to/src.

Более надежное решение - особенно если вы собираетесь зеркалировать / создавать версии этих сценариев на машинах нескольких разработчиков.- сделать вашу работу по разработке в контролируемой виртуальной среде.Оказывается, в virtualenv даже есть встроенная поддержка для создания собственных настроек начальной загрузки .Похоже, вам просто понадобится хук after_install() для настройки sitecustomize, запуска pip install -e или добавления простого файла .pth в пакеты сайтов.Пользовательский загрузчик может находиться в вашем контроле исходного кода вместе с другими сценариями, и его необходимо будет запускать один раз для настройки каждого разработчика.У вас также были бы обычные преимущества использования virtualenv (явное управление версиями зависимостей, изоляция от общесистемной конфигурации и стандартизация между разнородными машинами и многие другие).

Если вы действительно если вы не хотите выполнять какие-либо шаги по установке и готовы только запускать эти сценарии из каталога 'project', то вы можете добавить __init__.py в виде:

project/
    src/
        some_module.py
    scripts/
        __init__.py # special "magic"
        some_script.py

И вот как могут выглядеть ваши файлы:

# file: project/src/some_module.py
print("importing %r" % __name__)

def some_function():
    print("called some_function() inside %s" % __name__)
--------------------------------------------------------
# file: project/scripts/some_script.py
import some_module

if __name__ == '__main__':
    some_module.some_function()
--------------------------------------------------------
# file: project/scripts/__init__.py
import sys
from os.path import dirname, abspath, join

print("doing magic!")
sys.path.insert(0, join(dirname(dirname(abspath(__file__))), 'src'))

Тогда вам придется запускать ваши скрипты так:

[~/project] $ python -m scripts.some_script
doing magic!
importing 'some_module'
called some_function() inside some_module

Осторожно!Сценарии можно только вызывать так изнутри project/:

[~/otherdir] $ python -m scripts.some_script
ImportError: no module named scripts

Чтобы включить это, вы вернулись к редактированию .bashrc или к одному из приведенных выше вариантов.,Последний вариант действительно должен быть последним средством;как сказал @Simon, вы действительно боретесь с языком на этом этапе.

0 голосов
/ 31 августа 2011

вы можете добавить файл с именем 'pathHack.py' в каталог проекта и поместить в него что-то вроде этого:

import os
import sys
pkgDir = os.path.dirname(__file__)
sys.path.insert(os.path.join(pkgDir, 'scripts')

затем, в файле python в каталоге проекта, начните с:1004 *

import pathHack

и теперь вы можете импортировать вещи из директории скриптов без «скриптов».префикс.Если у вас есть только один файл в этом каталоге, и вы не хотите скрывать подобные вещи, вы можете вставить этот фрагмент.

0 голосов
/ 31 августа 2011

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

Что-то звучит странно в том, что вы пытаетесь сделать.Можете ли вы показать нам пример того, чего вы пытаетесь достичь?

...