Könnte mir jemand eine gute Möglichkeit bieten, ein ganzes Verzeichnis von Modulen zu importieren?
Ich habe eine Struktur wie diese:
/Foo
bar.py
spam.py
eggs.py
Ich habe versucht, es einfach durch Hinzufügen __init__.py
und Ausführen in ein Paket umzuwandeln , from Foo import *
aber es hat nicht so funktioniert, wie ich es mir erhofft hatte.
python
python-import
Evan Fosmark
quelle
quelle
Antworten:
Listen Sie alle python (
.py
) - Dateien im aktuellen Ordner auf und fügen Sie sie als__all__
Variable ein__init__.py
quelle
if not os.path.basename(f).startswith('_')
oder zumindestif not f.endswith('__init__.py')
bis zum Ende des Listenverständnissesos.path.isfile(f)
istTrue
. Das würde kaputte Symlinks und Verzeichnisse wiesomedir.py/
(from . import *
nach der Einstellung ,__all__
wenn Sie Submodule zur Verfügung stehen mit wollen.
(zB wiemodule.submodule1
,module.submodule2
usw.).Fügen Sie die
__all__
Variable zu folgendem hinzu__init__.py
:Siehe auch http://docs.python.org/tutorial/modules.html
quelle
os.listdir()
etwas Filtern, Entfernen der.py
Verlängerung und__all__
.moduleName.varName
. stackoverflow.com/a/710603/248616Update 2017: Sie möchten wahrscheinlich
importlib
stattdessen verwenden.Machen Sie das Foo-Verzeichnis zu einem Paket, indem Sie ein hinzufügen
__init__.py
. Fügen Sie__init__.py
hinzu:Da Sie möchten, dass es dynamisch ist (was eine gute Idee sein kann oder nicht), listen Sie alle py-Dateien mit dem Listenverzeichnis auf und importieren Sie sie wie folgt:
Dann machen Sie von Ihrem Code aus Folgendes:
Sie können jetzt mit auf die Module zugreifen
usw.
from Foo import *
ist aus mehreren Gründen keine gute Idee, einschließlich Namenskonflikten und der Schwierigkeit, den Code zu analysieren.quelle
__import__
hackish, ich denke, es wäre besser, die Namen hinzuzufügen__all__
und dannfrom . import *
am Ende des Skripts zu setzen__import__
ist nicht für allgemeineinterpreter
Zwecke , sondern wird vonimportlib.import_module()
stattdessen verwendet.from . import eggs
etc. machen,__init__.py
bevor Python importieren konnte. Mit nurimport eggs
bekomme ichModuleNotFoundError: No module named 'eggs'
beim Versuchimport Foo
in dasmain.py
im Verzeichnis oben.Ausgehend von Mihails Antwort glaube ich, dass der nicht-hackige Weg (wie in, die Dateipfade nicht direkt zu behandeln) der folgende ist:
__init__.py
Datei unterFoo/
Du wirst kriegen:
quelle
RuntimeWarning
Nachrichten können auch vermieden werden, indem full_package_name überhaupt nicht verwendet wird :importer.find_module(package_name).load_module(package_name)
.RuntimeWarning
Fehler können auch (auf wohl hässliche Weise) durch Importieren des übergeordneten Elements (AKA-Verzeichnisname) vermieden werden. Ein Weg, dies zu tun, ist -if dirname not in sys.modules: pkgutil.find_loader(dirname).load_module(dirname)
. Das funktioniert natürlich nur, wenndirname
es sich um einen relativen Einkomponentenpfad handelt. keine Schrägstriche. Persönlich bevorzuge ich den Ansatz von @ Artfunkel, stattdessen den Basispaketnamen zu verwenden.Python, schließen Sie alle Dateien in ein Verzeichnis ein:
Für Neulinge, die es einfach nicht zum Laufen bringen können und ihre Hände halten müssen.
Erstellen Sie einen Ordner / home / el / foo und erstellen Sie eine Datei
main.py
unter / home / el / foo. Geben Sie diesen Code dort ein:Erstellen Sie ein Verzeichnis
/home/el/foo/hellokitty
Machen Sie eine Datei
__init__.py
unter/home/el/foo/hellokitty
und geben Sie diesen Code dort ein:Erstellen Sie zwei Python-Dateien:
spam.py
undham.py
unter/home/el/foo/hellokitty
Definieren Sie eine Funktion in spam.py:
Definieren Sie eine Funktion in ham.py:
Starte es:
quelle
import *
wird jedoch als schlechte Python-Codierungspraxis angesehen. Wie machst du das ohne das?Ich habe dieses Problem selbst satt und schrieb ein Paket namens automodinit, um es zu beheben. Sie können es von http://pypi.python.org/pypi/automodinit/ erhalten .
Die Verwendung ist wie folgt:
automodinit
Paket in Ihresetup.py
Abhängigkeiten ein.Das ist es! Von nun an setzt das Importieren eines Moduls __all__ auf eine Liste von .py [co] -Dateien im Modul und importiert auch jede dieser Dateien so, als hätten Sie Folgendes eingegeben:
Daher stimmt der Effekt von "von M import *" genau mit "import M" überein.
automodinit
läuft gerne in ZIP-Archiven und ist daher ZIP-sicher.Niall
quelle
Ich weiß, dass ich einen ziemlich alten Beitrag aktualisiere, und ich habe versucht, ihn zu verwenden
automodinit
, aber festgestellt, dass der Einrichtungsprozess für Python3 unterbrochen ist. Basierend auf Lucas Antwort habe ich eine einfachere Antwort auf dieses Problem gefunden, die mit .zip möglicherweise nicht funktioniert. Deshalb habe ich mir vorgenommen, sie hier zu teilen:innerhalb des
__init__.py
Moduls vonyourpackage
:und in einem anderen Paket unten
yourpackage
:Dann werden alle Module, die im Paket enthalten sind, geladen. Wenn Sie ein neues Modul schreiben, wird es ebenfalls automatisch importiert. Verwenden Sie solche Dinge natürlich mit Sorgfalt, mit großen Kräften geht eine große Verantwortung einher.
quelle
quelle
Ich bin auch auf dieses Problem gestoßen und dies war meine Lösung:
Diese Funktion erstellt eine Datei (im bereitgestellten Ordner) mit dem Namen
__init__.py
, die eine__all__
Variable enthält , die jedes Modul im Ordner enthält.Zum Beispiel habe ich einen Ordner mit dem Namen
Test
:In das Skript, in das die Module importiert werden sollen, schreibe ich:
Dadurch wird alles importiert
Test
und die__init__.py
DateiTest
enthält nun:quelle
Anurags Beispiel mit ein paar Korrekturen:
quelle
Anurag Uniyal Antwort mit Verbesserungsvorschlägen!
quelle
Sehen Sie, dass Ihre
__init__.py
Definitionen__all__
. Das Modul - Pakete doc sagtquelle
Dies ist der beste Weg, den ich bisher gefunden habe:
quelle
Mit
importlib
das einzige , was du hast hinzuzufügen istquelle
error: Type of __all__ must be "Sequence[str]", not "List[Module]"
. Eine Definition__all__
ist nicht erforderlich, wenn dieserimport_module
basierte Ansatz verwendet wird.Schauen Sie sich das pkgutil-Modul aus der Standardbibliothek an. Damit können Sie genau das tun, was Sie wollen, solange Sie eine
__init__.py
Datei im Verzeichnis haben. Die__init__.py
Datei kann leer sein.quelle
Ich habe dafür ein Modul erstellt, das nicht auf
__init__.py
(oder einer anderen Zusatzdatei) basiert und mich nur die folgenden zwei Zeilen eingeben lässt:Fühlen Sie sich frei, wiederzuverwenden oder beizutragen: http://gitlab.com/aurelien-lourot/importdir
quelle
Importieren Sie sie einfach per importlib und fügen Sie sie
__all__
(add
Aktion ist optional) rekursiv im__init__.py
of-Paket hinzu.quelle
py
Wenn
from . import *
es nicht gut genug ist, ist dies eine Verbesserung gegenüber der Antwort von Ted . Insbesondere ist die Verwendung von__all__
bei diesem Ansatz nicht erforderlich.Beachten Sie, dass
module_name not in globals()
das Modul nicht erneut importiert werden soll, wenn es bereits importiert wurde, da dies zu zyklischen Importen führen kann.quelle