2010-09-09 19 views
11

Sto cercando di capire un'altra cosa magica di django: può convertire stringhe in moduli.In che modo django converte string in moduli

In settings.py, INSTALLED_APPS viene dichiarata così:

INSTALLED_APPS = (
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
) 

tutto ciò che contiene è stringhe. Ma django convertirà quelle stringhe in moduli e li importerà in seguito.

Voglio essere in grado di fare la stessa cosa. ma non so come. Ho un dizionario di rendering dispatcher in settings.py:

RESOUCE_RENDERER = { 
    'video': 'video_player', 
    'audio': 'audio_player', 
} 

voglio usare in un secondo momento come questo: RESOURCE_RENDERER['video'](MyVideo).

Non riesco ad assegnare direttamente il nome della funzione (ad esempio video_player) perché risiede in un modulo che richiede settings.py.

risposta

8

Dal momento che Django 1.7 è a simple function for this. Per esempio:

from django.utils.module_loading import import_string 
my_module = import_string('path.to.my_module') 

È inoltre possibile ottenere le classi dal modulo:

MyClass = import_string('path.to.my_module.MyClass') 
8

Date un'occhiata a django.conf.__init__.py, ma in fondo si utilizza importlib in questo modo:

try: 
    mod = importlib.import_module(self.SETTINGS_MODULE) 
except ImportError, e: 
    raise ImportError("Could not import settings '%s' 
       (Is it on sys.path? Does it have syntax errors?): 
       %s" % (self.SETTINGS_MODULE, e)) 

# Settings that should be converted into tuples if they're mistakenly entered 
# as strings. 
tuple_settings = ("INSTALLED_APPS", "TEMPLATE_DIRS") 

Edit: Su richiesta del PO ho ampliato l'esempio e ha contribuito un po 'più in basso.

Ora, si supponga di avere un elenco di funzioni in questo modulo, definito ad esempio FUNZIONI DA CHIAMARE, un elenco di funzioni. Quindi, si potrebbe chiamare ogni in questo modo:

ARGUMENTS = '()' 

for FUNCTION in FUNCTIONS_TO_CALL: 
    function_string = FUNCTION + ARGUMENTS 
    exec(function_string) 

Ciò presuppone ogni funzione ha lo stesso insieme di argomenti definiti. È possibile utilizzare un'istruzione if per rilevare il nome della funzione elencato dall'utente e fornire argomenti personalizzati a seconda di cosa sia. Si potrebbe anche valutare leggendo il file python quali dovrebbero essere gli argomenti.

Si può anche controllare l'oggetto modulo (presumo che sia possibile, non so) verificare se tale funzione esiste prima di chiamare exec() o eval(). Non so, ancora una volta, se si può valutare dall'oggetto funzione quali argomenti richiede. Sospetto di sì, ma questa è una domanda separata (forse già risposta?).

+0

@Ninefingers, questo aiuterebbe, ma cerco di importare funzioni, non solo i moduli. Sai come posso riuscirci? – maroxe

+0

Immagino che __import__ sia quello che sto cercando – maroxe

+0

Sì e no. L'istruzione import è un wrapper per le funzioni importlib, in quanto tale, quando ti diverti import_module hai * importato * un modulo variabile * come se * avessi chiesto "import somevariable". Non penso che tu possa importare i nomi delle variabili, ma puoi farlo tramite questa libreria. Ora, una volta che hai importato un modulo hai accesso a tutto ciò che contiene, ho ampliato l'esempio sopra per includere il codice che accede a "INSTALLED_APPS" dal file delle impostazioni, come discusso nel q. –

Problemi correlati