Python: Importieren eines Unterpakets oder eines Untermoduls

Da ich bereits flache Pakete verwendet habe, habe ich das Problem mit verschachtelten Paketen nicht erwartet. Hier ist…

Verzeichnislayout
dir
 |
 +-- test.py
 |
 +-- package
      |
      +-- __init__.py
      |
      +-- subpackage
           |
           +-- __init__.py
           |
           +-- module.py
Inhalt vondrin.py

Beidepackage/__init__.py undpackage/subpackage/__init__.py sind leer.

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

Das ist die schlechte und unsichere Art, Dinge zu importieren (alles in großen Mengen zu importieren), aber es funktioniert.

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

Ein sicherer Weg, Artikel für Artikel zu importieren, aber es schlägt fehl, Python möchte dies nicht: schlägt mit der Meldung fehl: "Kein Modul namens Modul". Jedoch …

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

… Sagt<module 'package.subpackage.module' from '...'>. Das ist also ein Modul, aber das ist kein Modul / -P 8-O ... ähm

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

Dieser funktioniert. Sie sind also entweder gezwungen, das Overkill-Präfix die ganze Zeit zu verwenden, oder Sie verwenden die unsichere Methode wie in Version 1 und Python untersagt, die sichere, handliche Methode zu verwenden? Der bessere Weg, der sicher ist und unnötige lange Präfixe vermeidet, ist der einzige, den Python ablehnt? Ist das, weil es liebtimport * oder weil es überlange Präfixe liebt (was nicht hilft, diese Praxis durchzusetzen) ?.

Tut mir leid für die harten Worte, aber das sind zwei Tage, in denen ich versuche, dieses dumme Verhalten zu umgehen. Wenn ich nicht irgendwo total falsch lag, habe ich das Gefühl, dass etwas in Pythons Modell von Paketen und Unterpaketen wirklich kaputt ist.

Anmerkungen

Darauf möchte ich mich nicht verlassensys.path, um globale Nebenwirkungen zu vermeiden, noch weiter*.pth Dateien, die nur eine andere Art des Spielens sindsys.path mit den gleichen globalen Wirkungen. Damit die Lösung sauber ist, muss sie nur lokal sein. Entweder kann Python mit Unterpaketen umgehen, oder nicht, aber es sollte nicht erforderlich sein, mit der globalen Konfiguration zu spielen, um mit lokalen Dingen umgehen zu können.Ich habe auch versucht, Importe zu verwendenpackage/subpackage/__init__.py, aber es hat nichts gelöst, es macht das gleiche und beschwert sichsubpackage ist kein bekanntes Modul, währendprint subpackage sagt, es ist ein Modul (wieder seltsames Verhalten).

Es mag sein, dass ich völlig falsch liege (die Option, die ich vorziehen würde), aber das enttäuscht mich sehr über Python.

Gibt es einen anderen bekannten Weg als den, den ich ausprobiert habe? Etwas, von dem ich nichts weiß?

(Seufzer)

-----% <----- bearbeiten ----->% -----

Fazit bisher (nach Kommentaren der Leute)

In Python gibt es nichts Besseres als ein echtes Unterpaket, da alle Paketreferenzen nur auf ein globales Wörterbuch verweisen. Dies bedeutet, dass es kein lokales Wörterbuch gibt, was impliziert, dass es keine Möglichkeit gibt, lokale Paketreferenzen zu verwalten.

Sie müssen entweder das vollständige Präfix oder das kurze Präfix oder den Alias ​​verwenden. Wie in:

Volle Präfixversion
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Kurzpräfixversion (aber wiederholtes Präfix)
from package.subpackage import module
# Short but then you have to do:
use_of (module.attribute1)
# and repeat the prefix at every use place

Oder eine Variation des oben genannten.

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
Faktorisierte Version

Wenn Sie nicht möchten, dass mehrere Entitäten gleichzeitig in einem Stapel importiert werden, haben Sie folgende Möglichkeiten:

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

Nicht in meinem ersten Lieblingsgeschmack (ich bevorzuge eine Importabrechnung pro importierter Entität), aber vielleicht die, die ich persönlich favorisieren werde.

Update (14.09.2012):

Scheint schließlich in der Praxis in Ordnung zu sein, außer mit einem Kommentar zum Layout. Stattdessen habe ich Folgendes verwendet:

from package.subpackage.module import (

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

Antworten auf die Frage(3)

Ihre Antwort auf die Frage