Python: импорт подпакета или субмодуля

Уже использовав плоские пакеты, я не ожидал, что возникнет проблема с вложенными пакетами. Вот & # x2026;

Directory layout
dir
 |
 +-- test.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- module.py
Content of init.py

И то и другоеpackage/__init__.py а такжеpackage/subpackage/__init__.py пусты

Content of module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
Content of test.py (3 versions) Version 1
# file test.py
from package.subpackage.module import *
print attribute1 # OK

Это плохой и небезопасный способ импортировать вещи (импортировать все навалом), но это работает.

Version 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1

Более безопасный способ импортировать элемент за элементом, но он терпит неудачу, Python не хочет этого: происходит сбой с сообщением: «Нет модуля с именем module». Однако & # xA0; & # x2026;

# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
print module # Surprise here

& # X2026; & # xA0, говорит<module 'package.subpackage.module' from '...'>, Так что это модуль, но это не модуль / -P 8-O ... э-э

Version 3
# file test.py v3
from package.subpackage.module import attribute1
print attribute1 # OK

Этот работает. Таким образом, вы либо вынуждены все время использовать префикс overkill, либо использовать небезопасный способ, как в версии # 1, и Python запрещает использовать безопасный удобный способ? Лучший способ, который является безопасным и позволяет избежать ненужного длинного префикса, является единственным, который Python отклоняет? Это потому что любитimport * или потому что он любит слишком длинные префиксы (что не помогает применять эту практику)?

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

Заметки

I don't want to rely on sys.path, to avoid global side effects, nor on *.pth files, which are just another way to play with sys.path with the same global effets. For the solution to be clean, it has to be local only. Either Python is able to handle subpackage, either it's not, but it should not require to play with global configuration to be able to handle local stuff. I also tried use imports in package/subpackage/__init__.py, but it solved nothing, it do the same, and complains subpackage is not a known module, while print subpackage says it's a module (weird behavior, again).

Может быть, я совершенно не прав (такой вариант я бы предпочел), но это заставляет меня сильно разочаровываться по поводу Python.

Любой другой известный способ кроме трех я попробовал? Что-то, о чем я не знаю?

(вздох)

-----% & lt; ----- изменить ----- & gt;% -----

Conclusion so far (after people's comments)

В Python нет ничего похожего на настоящий пакет sub & # x2011; все ссылки на пакеты идут только в глобальный словарь, что означает отсутствие локального словаря, что означает, что нет никакого способа управлять ссылкой на локальный пакет.

Вы должны использовать полный префикс или короткий префикс или псевдоним. Как в:

Full prefix version
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Short prefix version (but repeated prefix)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place

Или иначе, вариант выше.

from package.subpackage import module as m
use_of (m.attribute1)
# `m` is a shorter prefix, but you could as well
# define a more meaningful name after the context
Factorized version

Если вы не хотите импортировать сразу несколько объектов одновременно, вы можете:

from package.subpackage.module import attribute1, attribute2
# and etc.

Не в моем первом любимом вкусе (я предпочитаю иметь одно утверждение импорта для каждой импортируемой сущности), но, возможно, я буду предпочитать его лично.

Update (2012-09-14):

Наконец, на практике все в порядке, кроме как с комментарием о макете. Вместо вышеупомянутого я использовал:

from package.subpackage.module import (

    attribute1, 
    attribute2,
    attribute3,
    ...)  # and etc.

Ответы на вопрос(3)

Ваш ответ на вопрос