Nachdem ich bereits Flat-Pakete verwendet hatte, hatte ich das Problem mit verschachtelten Paketen nicht erwartet. Hier ist…
Verzeichnislayout
dir
|
+-- test.py
|
+-- package
|
+-- __init__.py
|
+-- subpackage
|
+-- __init__.py
|
+-- module.py
Inhalt von init .py
Beide package/__init__.py
und package/subpackage/__init__.py
sind leer.
Inhalt von module.py
# file `package/subpackage/module.py`
attribute1 = "value 1"
attribute2 = "value 2"
attribute3 = "value 3"
# and as many more as you want...
Inhalt von test.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 importieren), aber es funktioniert.
Version 2
# file test.py
import package.subpackage.module
from package.subpackage import module # Alternative
from module import attribute1
Eine sicherere Möglichkeit, Artikel für Artikel zu importieren, aber dies schlägt fehl. Python möchte dies nicht: schlägt mit der Meldung fehl: "Kein Modul mit dem Namen 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 gezwungen, entweder ständig das Overkill-Präfix zu verwenden oder den unsicheren Weg wie in Version 1 zu verwenden, und von Python nicht zugelassen, den sicheren praktischen Weg zu verwenden? Der bessere Weg, der sicher ist und unnötiges langes Präfix vermeidet, ist der einzige, den Python ablehnt? Liegt es daran, dass es liebt import *
oder dass es überlange Präfixe liebt (was nicht dazu beiträgt, diese Praxis durchzusetzen)?
Entschuldigen Sie die harten Worte, aber das sind zwei Tage, an denen ich versuche, dieses dumme Verhalten zu umgehen. Wenn ich mich nicht irgendwo völlig geirrt habe, habe ich das Gefühl, dass etwas in Pythons Modell von Paketen und Unterpaketen wirklich kaputt ist.
Anmerkungen
- Ich möchte mich nicht auf
sys.path
globale Nebenwirkungen verlassen , um globale Nebenwirkungen zu vermeiden, und auch nicht auf*.pth
Dateien, die nur eine andere Möglichkeit sind,sys.path
mit denselben globalen Effekten zu spielen . Damit die Lösung sauber ist, muss sie nur lokal sein. Entweder ist Python in der Lage, Unterpakete zu verarbeiten, oder auch nicht, aber es sollte nicht erforderlich sein, mit der globalen Konfiguration zu spielen, um lokale Inhalte verarbeiten zu können. - Ich habe auch versucht, Importe zu verwenden
package/subpackage/__init__.py
, aber es hat nichts gelöst, es macht dasselbe und beschwert sich, dasssubpackage
es kein bekanntes Modul ist, während esprint subpackage
sagt , dass es ein Modul ist (wieder seltsames Verhalten).
Vielleicht bin ich völlig falsch hart (die Option, die ich bevorzugen würde), aber das macht mich sehr enttäuscht über Python.
Gibt es einen anderen bekannten Weg neben den drei, die ich versucht habe? Etwas, von dem ich nichts weiß?
(Seufzer)
-----% <----- edit ----->% -----
Fazit bisher (nach den 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 bedeutet, 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:
Vollständige Präfixversion
from package.subpackage.module import attribute1
# An repeat it again an again
# But after that, you can simply:
use_of (attribute1)
Kurze Prä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 der 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 es Ihnen nichts ausmacht, mehrere Entitäten gleichzeitig in einem Stapel zu importieren, können Sie:
from package.subpackage.module import attribute1, attribute2
# and etc.
Nicht in meinem ersten Lieblingsgeschmack (ich bevorzuge eine Importanweisung pro importierter Entität), aber möglicherweise die, die ich persönlich bevorzugen werde.
Update (14.09.2012):
Schließlich scheint es in der Praxis in Ordnung zu sein, außer mit einem Kommentar zum Layout. Anstelle der oben genannten habe ich verwendet:
from package.subpackage.module import (
attribute1,
attribute2,
attribute3,
...) # and etc.