2010-09-09 11 views
11

Ich versuche, eine andere magische Sache über Django zu verstehen: Es kann Strings in Module konvertieren.Wie konvertiert Django String in Module

In settings.py wird INSTALLED_APPS so erklärt:

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

Alles, was es ist Strings enthält. Django konvertiert diese Zeichenfolgen in Module und importiert sie später.

Ich möchte in der Lage sein, das Gleiche zu tun. aber ich weiß nicht wie. Ich habe ein Wörterbuch der Renderer Dispatcher in settings.py:

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

Ich möchte es so später verwenden: RESOURCE_RENDERER['video'](MyVideo).

Ich kann den Funktionsnamen (zB video_player) nicht direkt zuweisen, weil es in einem Modul lebt, das settings.py benötigt.

Antwort

8

Seit Django 1.7 gibt es a simple function for this. Zum Beispiel:

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

Sie auch Klassen aus dem Modul bekommen:

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

Werfen Sie einen Blick in django.conf.__init__.py, aber im Grunde verwendet es importlib wie so:

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") 

bearbeiten: Auf Antrag des OP ich das Beispiel erweitert haben und einige mehr unter beigetragen.

Angenommen, Sie hatten eine Liste von Funktionen in diesem Modul, die z. B. in FUNCTIONS TO CALL definiert sind, eine Liste von Funktionen. Dann könnten Sie jedes wie folgt anrufen:

ARGUMENTS = '()' 

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

Dies setzt voraus, dass jede Funktion den gleichen Satz von definierten Argumenten hat. Sie können eine if-Anweisung verwenden, um den vom Benutzer aufgelisteten Funktionsnamen zu erkennen und abhängig davon, was dies ist, benutzerdefinierte Argumente zu liefern. Sie können auch beim Lesen der Python-Datei bewerten, wie die Argumente lauten sollen.

Sie könnten auch das Modul Objekt zu überprüfen (ich nehme an, das ist möglich, ich weiß es nicht) sehen, ob diese Funktion existiert vor dem Aufruf exec() oder eval(). Ich weiß es auch nicht, wenn man vom Funktionsobjekt beurteilen kann, welche Argumente es braucht. Ich vermute das, aber das ist eine separate (möglicherweise bereits beantwortete?) Frage.

+0

@Ninefingers, würde dies helfen, aber ich bin auf der Suche Funktionen zu importieren, nicht nur Module. Weißt du, wie ich das erreichen kann? – maroxe

+0

ich denke, __import__ ist was ich suche – maroxe

+0

Ja und nein. Die import-Anweisung ist ein Wraparound für die importlib-Funktionen. Wenn Sie also Spaß haben, importieren Sie * ein * * importiertes Variablenmodul * so, als hätten Sie nach "importjuniable" gefragt. Ich glaube nicht, dass Sie Variablennamen "importieren" können, aber Sie können über diese Bibliothek. Jetzt, nachdem Sie ein Modul importiert haben, haben Sie Zugriff auf alles darin - ich habe das obige Beispiel so erweitert, dass es den Code enthält, der auf 'INSTALLED_APPS' aus der Einstellungsdatei zugreift, wie Sie in q besprochen haben. –

Verwandte Themen