2013-11-27 2 views
9

У меня есть каталог с пакетом питона следующим образом:сфинкс и относительный импорт в Python 3. *

--docs/index.rst 
--docs/... 
--app/__init__.py 
--app/foo.py 

, и я использую сфинкс с autodocs для документирования приложения (в питоне 3.3).

Теперь в conf.py (внутри docs/), у меня есть

sys.path.insert(0, os.path.abspath('../app')) 

Я cd в docs/, запустить

make html 

, который дает мне

SystemError: модуль Parent '' не не может выполнять относительный импорт

для всех модулей, которые имеют

from .foo import Bar 

У меня есть чистый virtualenv установка Сфинкса с использованием

pip install Sphinx 

после того, как я создал (чистую) среду для питона 3.3.

Что мне не хватает?

Я перемещал проект с python 2. * на python 3. *, когда это произошло. Весь проект работает, но это ...

+0

Действительно ли 'app' сам пакет верхнего уровня или каталог, в котором находятся пакеты верхнего уровня? – abarnert

+0

Я не уверен, что понял ваш вопрос @abarnert. 'app' не имеет каталога внутри, просто набор' * .py', включая '__init __. py'. sphinx только документы app dir. –

+0

Если 'app' имеет' __init __. Py' внутри, то это пакет. И это твоя проблема. Позвольте мне написать ответ, чтобы объяснить. – abarnert

ответ

14

Ваш app каталог представляет собой пакет. Пакет представляет собой каталог с __init.py__ и другими файлами внутри него.

Если вы поместите каталог пакетов на свой sys.path, всевозможные вещи идут не так.

Давайте рассмотрим пример:

root/ 
    app/ 
     app/__init__.py 
     app/spam.py 
     app/eggs.py 

Если у вас есть root на вашем sys.path (потому что это текущий рабочий каталог, или потому, что вы делаете это в явном виде, или потому, что вы правильно установили вещи ваш site-packages), то app - это пакет, app.spam - это модуль, и в пределах app.eggs, .spam - это тот модуль. Итак, все работает.

Если у вас есть app на вашем sys.path, то app не пакет, spam является модулем, и, в eggs, .spam нет ничего. Таким образом, вы не можете использовать относительный импорт.

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


Так что, скорее всего, вы хотите исправить это:

sys.path.insert(0, os.path.abspath('..')) 

Если есть другие пакеты, или каталоги, полные кода Python, которые не являются пакеты, в .., что вы не» т хотите AutoDoc (например, tests каталог с tests/test_spam.py), то вам нужно будет перестроить свои каталоги, чтобы положить app в какой-нибудь каталог, который не имеет какой-либо другой код Python в нем, как это:

root/ 
    src/ 
     app/ 
    tests/ 
    doc/ 

В качестве альтернативы, если вы не хотите app быть пакет, а быть каталог sys.path корень, а затем убить __init__.py и оставить app непосредственно в sys.path. Но в этом случае вы не можете использовать относительный импорт внутри пакета; все модули в app являются модулями верхнего уровня и должны быть импортированы как таковые.


Packages раздел учебника (и остальной части главы над ним) объясняет некоторые из этого, но, вероятно, лучше вводная документация там.

Для получения более подробной информации, в 3.3+, The import system есть все, красиво организовано; для более старых версий эталонные документы грязны, неполны и разбросаны; вы должны начинать с The import statement, а затем читать The Knights Who Say Neeeow ... Wum ... Ping! (в основном это PEP, а 1.5 еще не имеют PEP) и, возможно, даже документацию ni, если вы можете ее найти, а также различные записи PEP и незначительные записи журнала изменений, которые объясняют как все изменилось между 1,5 и 2,7 или 3,2 или что-то еще.

+0

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

+2

@ J.C.Leitão: Если вы делали то же самое в Python 2.x, это тоже было неправильно. Это просто, что 2.7 позволяет вам уйти с написанием материала, который находится на полпути между стилем Python 1.5 и стилем Python-3.3, и иногда он работает ... – abarnert

Смежные вопросы