Вынужден использовать несовместимые пути импорта файлов в Python (/ Django) - PullRequest
4 голосов
/ 21 июля 2009

Недавно у меня возникли некоторые проблемы с импортом в Django (Python) ... Это лучше объяснить с помощью файловой диаграммы:

- project/
    - application/
        - file.py
    - application2/
        - file2.py

В project/application/file.py У меня есть следующее:

def test_method():
    return "Working"

Проблема возникает в project/application2/file2.py, когда я пытаюсь импортировать метод сверху:

from application.file import test_method

Обычно работает, но иногда нет.

from project.application.file import test_method

Работает, но идет вразрез с принципами переносимости Django, поскольку папка проекта всегда должна называться одинаково.

Я бы не возражал, но это факт, что эта проблема возникает непоследовательно, в большинстве случаев пропуск project это хорошо, но иногда нет (и, насколько я вижу, без причины). *

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

Ответы [ 3 ]

4 голосов
/ 21 июля 2009

Для импорта, чтобы найти модуль, он должен быть либо в sys.path. Обычно это включает "", поэтому он ищет текущий каталог. Если вы загрузите «приложение» из проекта, оно найдет его, поскольку оно находится в текущем каталоге.

Хорошо, это очевидные вещи. Смущает то, что Python запоминает, какие модули загружены. Если вы загружаете приложение, то вы загружаете приложение2, которое импортирует приложение, модуль «приложение» уже загружен. Это не должно найти это на диске; он просто использует тот, который уже загружен. С другой стороны, если вы еще не загрузили приложение, оно будет искать его - и не найдет его, поскольку оно не находится в том же каталоге, что и его загрузка ("."), Или где-либо еще в путь.

Это может привести к странному случаю, когда импорт иногда работает, а иногда нет; он работает только если он уже загружен.

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

(Звук относительного импорта связан, но кажется, что application и application2 - это отдельные пакеты - относительный импорт используется для импорта в одном пакете.)

Наконец, обязательно последовательно относитесь ко всему как к пакету или последовательно относитесь к каждому приложению как к своему пакету. Не смешивать и сочетать. Если package / находится в пути (например, sys.path включает в себя package / ..), то вы действительно можете сделать «из пакета package.application import foo», но если вы затем также выполните «из приложения import foo», это возможно для Python, чтобы не понимать, что это одно и то же - их имена разные, и они идут разными путями - и в итоге загружают две разные его копии, которые вам определенно не нужны.

2 голосов
/ 21 июля 2009

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

from aplication.file import test_method

Это был бы способ Джанго сделать это. Гленн ответил, почему вы получаете свои ошибки, поэтому я не буду вдаваться в эту часть. Когда вы запускаете команду для запуска нового проекта:

django-admin.py startproject myproject
Это создаст папку с кучей файлов, которые нужны django, настройками manage.py, pyct, но это сделает для вас другое. Это поместит папку «myproject» в ваш путь к Python. Вкратце это означает, что любое приложение, которое вы поместите в эту папку, вы сможете импортировать, как показано выше. Вам не нужно использовать django-admin.py, чтобы начать проект, поскольку ничего волшебного не происходит, это всего лишь ярлык. Таким образом, вы можете размещать свои папки приложений где угодно, вам просто нужно, чтобы они находились по пути Python, чтобы вы могли импортировать их напрямую и сделать свой проект кода независимым, чтобы его можно было легко использовать в любом будущем проекте, следуя принципу DRY на котором построен джанго.
0 голосов
/ 21 июля 2009

Лучше всегда импортировать, используя один и тот же способ - скажем, используя project.app.models - потому что в противном случае вы можете обнаружить, что ваш модуль импортирован дважды, что иногда приводит к неясным ошибкам, как обсуждалось в этом вопросе .

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