Проблема пути поиска модуля Python - PullRequest
3 голосов
/ 06 октября 2009

Я пытаюсь работать в среде разработчика, но я нахожу проблемы в том, что python, похоже, использует модули из каталога site-packages. Я хочу, чтобы он использовал модули из моего каталога dev.

sys.path возвращает кучу директорий, как это

['', '/usr/lib/python26.zip', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/lib/python2.6/site-packages' etc

Это хорошо, он использует текущий каталог в качестве первого места поиска (по крайней мере, я так понимаю).

Хорошо, теперь, если я создаю, скажем, файл с именем command.py в текущем каталоге, все работает так, как я ожидал.

>>> import commands
>>> commands.__file__
   'commands.pyc'

Затем я выхожу из оболочки python и запускаю другую. Затем я делаю это.

>>> import foo.bar.commands

Теперь я ожидаю, что он перейдет из текущего каталога в ./foo/bar/ и оттуда получит модуль команд. Что я получаю, хотя это

>>> foo.bar.commands.__file__
    '/usr/lib/python2.6/site-packages/foo/bar/commands.pyc'

Хотя из моего текущего каталога есть ./foo/bar/commands.py

Используя imp.find_module () и imp.load_module (), я могу правильно загрузить локальный модуль. Что действительно интересно (хотя я действительно не знаю, что это значит) - это последняя строка, напечатанная в этой последовательности

>>> import foo.bar.commands
>>> foo.bar.commands.__file__
   '/usr/lib/python2.6/site-packages/foo/bar/commands.pyc'
>>> foo.bar.__file__
   '/usr/lib/python2.6/site-packages/foo/bar/__int__.pyc'
>>> foo.__file__
    './foo/__init__.pyc'

Так что, если он может найти foo / init .pyc в локальном каталоге, почему он не может найти другие файлы в локальном каталоге?

Приветствия

Ответы [ 2 ]

3 голосов
/ 06 октября 2009

Вы упоминаете, что под вашим текущим каталогом есть каталог foo, но вы не говорите нам, существует ли foo/__init__.py (возможно, даже пустой): если это не так, это говорит Python, что foo есть не пакет. Аналогично для foo/bar/__init__.py - если этот файл не существует, даже если foo/__init__.py существует, то foo.bar не является пакетом.

Вы можете немного поиграться, поместив .pth файлы и / или явно указав __path__ в своих пакетах, но основное простое правило - просто поместить __init__.py в каждый каталог, который Python распознает. как пакет. Содержимое этого файла является «телом» самого пакета, поэтому, если вы import foo и foo - это каталог с файлом foo/__init__.py, то это то, что вы импортируете (в любом случае, тело пакета выполняется в первый раз, когда вы импортируете что-либо из пакета или любого его подпакета).

Если это не проблема, похоже, что какой-то другой импорт (или явное манипулирование sys.path) может сбить вас с толку. Запуск python с флагом -v делает импорт очень заметным, что может помочь. Еще одна хорошая техника - разместить

import pdb; pdb.set_trace()

непосредственно перед импортом, который, по вашему мнению, ведет себя некорректно, и проверяет sys.path, sys.modules (и, возможно, другие сложные структуры, такие как ловушки импорта) в этот момент - есть ли уже определенный sys.modules ['foo'] , например? Интерактивная проверка функций из стандартного библиотечного модуля imp, которые определяют местоположение модулей от вашего имени по заданному пути, также может оказаться поучительной.

0 голосов
/ 06 октября 2009

Что делает foo в /usr/lib/python2.6/site-packages? Похоже, вы создали foo в своем локальном каталоге, но это не обязательно тот, который вы импортируете.

Попробуйте избавиться от foo / bar в site-packages

Убедитесь, что ваша структура каталогов выглядит следующим образом

/foo/__init__.py  
    /bar/__init__.py
        /commands.py

Кроме того, не стоит повторно использовать имена стандартных библиотек python для своих собственных модулей. Можете ли вы назвать ваши commands.py как-нибудь еще?

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