Python: importowanie pod-pakietu lub podmodułu

Korzystając już z płaskich pakietów, nie spodziewałem się napotkanego problemu z zagnieżdżonymi pakietami. Tutaj jest…

Układ katalogu
dir
 |
 +-- test.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- module.py
Zadowolony zw tym.py

Obiepackage/__init__.py ipackage/subpackage/__init__.py są puste.

Zadowolony zmodule.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
Zadowolony ztest.py (3 wersje)Wersja 1
# file test.py
from package.subpackage.module import *
print attribute1 # OK

To zły i niebezpieczny sposób importowania rzeczy (importuj wszystko zbiorczo), ale działa.

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

Bezpieczniejszy sposób importowania, element po elemencie, ale nie powiedzie się, Python tego nie chce: kończy się niepowodzeniem z komunikatem: „Brak modułu o nazwie moduł”. Jednak …

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

… mówi<module 'package.subpackage.module' from '...'>. Więc to jest moduł, ale to nie jest moduł / -P 8-O ... uh

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

Ten działa. Czy więc jesteś zmuszony używać prefiksu overkill przez cały czas lub użyć niebezpiecznego sposobu, jak w wersji 1 i niedozwolonego przez Pythona do korzystania z bezpiecznego podręcznego sposobu? Lepszy sposób, który jest bezpieczny i pozwala uniknąć niepotrzebnego długiego przedrostka, jest jedynym, który Python odrzuca? Czy to dlatego, że kochaimport * lub dlatego, że kocha zbyt długie prefiksy (co nie pomaga w egzekwowaniu tej praktyki) ?.

Przepraszam za trudne słowa, ale to dwa dni, kiedy próbuję obejść to głupie zachowanie. Dopóki nie gdzieś się nie mylę, pozostawi mi to uczucie, że coś jest naprawdę zepsute w modelu pakietu i pod-pakietów Pythona.

Uwagi

Nie chcę na tym polegaćsys.path, aby uniknąć globalnych skutków ubocznych, ani na*.pth pliki, które są po prostu kolejnym sposobem zabawysys.path z tymi samymi globalnymi efektami. Aby rozwiązanie było czyste, musi być tylko lokalne. Albo Python jest w stanie obsłużyć podpakiet, albo nie, ale nie powinien wymagać gry z konfiguracją globalną, aby móc obsłużyć lokalne rzeczy.Próbowałem również użyć importupackage/subpackage/__init__.py, ale nic nie rozwiązało, robi to samo i narzekasubpackage nie jest znanym modułemprint subpackage mówi, że to moduł (znowu dziwne zachowanie).

Może jestem całkowicie zły (opcja, którą wolałbym), ale to sprawia, że ​​czuję się bardzo rozczarowany Pythonem.

Jakikolwiek inny znany sposób poza tymi trzema, których próbowałem? Coś o czym nie wiem?

(westchnienie)

-----% <----- edit ----->% -----

Dotychczasowe wnioski (po komentarzach ludzi)

W Pythonie nie ma niczego podobnego do rzeczywistego pod-pakietu, ponieważ wszystkie odwołania do pakietów trafiają tylko do globalnego słownika, co oznacza, że ​​nie ma lokalnego słownika, co oznacza, że ​​nie ma sposobu na zarządzanie odwołaniem do lokalnego pakietu.

Musisz użyć pełnego przedrostka lub krótkiego przedrostka lub aliasu. Jak w:

Pełna wersja prefiksu
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Wersja krótkiego przedrostka (ale powtórzony prefiks)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place

Albo inaczej, powyższa odmiana.

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
Wersja z faktoryzacją

Jeśli nie masz nic przeciwko zaimportowaniu wielu elementów jednocześnie w partii, możesz:

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

Nie w moim pierwszym ulubionym smaku (wolę mieć jedno oświadczenie dotyczące importu na importowany podmiot), ale może to być ten, który osobiście będę preferować.

Aktualizacja (2012-09-14):

Wreszcie wydaje się być w porządku w praktyce, z wyjątkiem komentarza na temat układu. Zamiast powyższego użyłem:

from package.subpackage.module import (

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

questionAnswers(3)

yourAnswerToTheQuestion