2009-06-29 3 views
15

Ich habe einen Nachrichtenordner (Paket) mit __init__.py Datei und ein weiteres Modul messages_en.py drin. In __init__.py wenn ich importieren messages_en es funktioniert, aber __import__ schlägt mit „Import: Keine Modul namens messages_en“Wie kann ich ein Paket mit __import __() importieren, wenn der Paketname nur zur Laufzeit bekannt ist?

import messages_en # it works 
messages = __import__('messages_en') # it doesn't ? 

Früher dachte ich, ‚Import x‘ ist nur eine andere Art zu sagen, __import__('x')

Antwort

14

Hinzufügen des Globals Argument ist für mich ausreichend:

__import__('messages_en', globals=globals()) 

In der Tat, nur __name__ ist benötigt hier:

__import__('messages_en', globals={"__name__": __name__}) 
14

__import__ eine ist interne Funktion, die von der import-Anweisung aufgerufen wird. Im täglichen Codierung Sie müssen (oder wollen) nicht __import__

aus Python-Dokumentation nennen:

Zum Beispiel die Aussage import spam Ergebnisse in Bytecode den folgenden Code ähnelt:

spam = __import__('spam', globals(), locals(), [], -1) 

Auf der Andererseits seits~~POS=HEADCOMP die Erklärung from spam.ham import eggs, sausage as saus Ergebnisse in

_temp = __import__('spam.ham', globals(), locals(), ['eggs', 'sausage'], -1) 
eggs = _temp.eggs 
saus = _temp.sausage 

weitere Informationen: http://docs.python.org/library/functions.html

+1

+1 und Dank für Erklärung, aber könnten Sie beschreiben genau, warum Das Beispiel von OP funktioniert nicht? Er scheint zu versuchen, messages_en auf Nachrichten zu aliasieren, was (naiv zu mir) vernünftig erscheint. –

+0

Wie 'wr' erklärt wurde, war es aufgrund der Ebene, und ich weiß, __import__ sollte normalerweise nicht verwendet werden, aber in diesem Fall muss ich Sprache aus einer Konfigurationsdatei dynamisch an Nachrichten lesen und diese Datei importieren –

+0

Dieses Beispiel war sehr hilfreich, vor allem, wenn Sie versuchen, Module aus Unterverzeichnissen zu laden. Es half mir, meinen Fehler "Attribut nicht gefunden" zu beheben. – Carlos

19

Wenn es ein Pfad Problem ist, sollten Sie das level Argument verwenden (von docs):

__import__(name, globals={}, locals={}, fromlist=[], level=-1) -> module 

Level is used to determine whether to perform 
absolute or relative imports. -1 is the original strategy of attempting 
both absolute and relative imports, 0 is absolute, a positive number 
is the number of parent directories to search relative to the current module. 
+2

aber ich frage mich, was war der Grund, weil Standard-Level ist -1, und ich bin immer noch -1, so nur extra sind globale/lokale dict, wie das einen Unterschied macht –

+0

Warum ist das die akzeptierte Antwort? Es beantwortet weder die Frage noch behebt es das Problem. – kynan

+0

Diese Antwort ist falsch. Das Problem des OP bezieht sich in keiner Weise auf "Ebene". Zwei Optionen, um es zu beheben: Entweder liefern Sie die Globals des Moduls als 'messages = __import __ ('messages_en', globals())', wie Eric hervorhebt oder den Paketnamen gibt, wie Lennart es vorschlägt. – kynan

0

Sie könnten versuchen, diese:

messages == __import__('Foo.messages_en', fromlist=['messages_en']) 
3

Seien Sie sicher, dass die Module Verzeichnis anhängen zu deinem Python-Pfad.

Ihr Pfad (die Liste der Verzeichnisse, durch die Python nach Modulen und Dateien sucht) ist im Pfadattribut des sys-Moduls gespeichert. Da der Pfad eine Liste ist, können Sie die Methode append verwenden, um dem Pfad neue Verzeichnisse hinzuzufügen.

Zum Beispiel das Verzeichnis/home/me/mypy auf den Pfad hinzuzufügen:

import sys 
sys.path.append("/home/me/mypy") 
+1

Das ist nicht sicher, da das Paket nicht verlagerbar ist. Es funktioniert nur, wenn das Paket in diesem fest codierten Pfad ist. – kynan

0

Sie müssen das oberste Paket Ihres dynamischen Paketpfades manuell importieren.

Zum Beispiel am Anfang der Datei i schreiben:

import sites 

dann später in Code funktioniert für mich:

target = 'some.dynamic.path' 
my_module = __import__ ('sites.%s.fabfile' % target, fromlist=["sites.%s" % target]) 
Verwandte Themen