питоновская организация модулей - как ссылаться на файлы в корневом каталоге?

Мой код python находится в папке под названием "project", поэтому мои файлы кода находятся в project/*.py. Я хочу иметь подмодули внутри него, например,

project/code.py # where code lives
project/mymodule1  # where more code lives
project/mymodule2

каждый каталог модуля имеет свой собственный init.py файл, например,

project/mymodule1/__init__.py

предположим, у меня есть файл "test.py" внутри mymodule1 (project/mymodule1/test. py) и я хочу обратиться к чему-то из "code", например, импортировать функцию "myfunc"

== project/mymodule1/test.py ==
from code import myfunc

проблема в том, что "code" не будет найден, если пользователь не поместил каталог "project/" в свой PYTHONPATH. Есть ли способ избежать этого и использовать какой-то "относительный путь" для импорта myfunc, например

from ../code import myfunc

В принципе, я не хочу заставлять пользователей кода изменять PYTHONPATH, если только я не могу сделать это программно для них из моего скрипта. Я бы хотел, чтобы это работало из коробки.

Как это можно сделать? Любое решение хорошо: изменение PYTHONPATH программно, или, что более идеально, обращение к "code" с помощью какого-то относительного импорта, поскольку даже если я не знаю, где "project/code.py" находится на компьютере пользователя, я знаю, где он находится относительно "myfunc".

EDIT: Кто-нибудь может показать правильный пример внутрипакетного импорта? Я пытался из "mymodule1" сделать:

from .. import foo

где "foo" находится в code.py, но это не работает. У меня есть init.py в mymodule1, поэтому:

project/code.py
project/mymodule1/__init__.py
project/mymodule1/module1_code.py

где module1_code.py пытается импортировать foo, функцию, определенную в "code.py".

EDIT: Основная путаница, которую я все еще испытываю, заключается в том, что даже после принятия примера, приведенного в ответ на мое сообщение, показывающего иерархию project/sub1/test, вы все еще не можете "cd" в sub1 и сделать "python test.py" и заставить его работать. Пользователь должен находиться в каталоге, содержащем "project", и сделать "import project.sub1.test". Я бы хотел, чтобы это работало независимо от того, в какой директории находится пользователь. Пользователь в этом случае должен выполнить файл "test.py", который находится в project/sub1/. Таким образом, тестовый пример:

$ cd project/sub1
$ python test.py

выдает ошибку:

ValueError: Attempted relative import in non-package

как это можно исправить?

спасибо.

6
задан 21 December 2011 в 02:04
поделиться