2010-09-09 7 views
11

? Estoy tratando de comprender otra cosa mágica sobre django: puede convertir cadenas en módulos.¿Cómo convierte django la cadena a los módulos

En settings.py, INSTALLED_APPS se declara así:

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

todo lo que contiene es cuerdas. Pero django convertirá esas cadenas en módulos y los importará más tarde.

Quiero hacer lo mismo. pero no sé cómo. tengo un diccionario de despachador de render en settings.py:

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

quiero usarlo más tarde como esto: RESOURCE_RENDERER['video'](MyVideo).

No puedo asignar directamente el nombre de la función (por ejemplo, video_player) porque vive en un módulo que necesita settings.py.

Respuesta

8

Desde Django 1.7 hay a simple function for this. Por ejemplo:

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

También puede obtener clases del módulo:

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

echa un vistazo en django.conf.__init__.py, pero básicamente se utiliza importlib así:

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

Editar: A petición de la OP he ampliado el ejemplo y he contribuido un poco más abajo.

Ahora, supongamos que tiene una lista de funciones en este módulo, definida, por ejemplo, en FUNCTIONS TO CALL, una lista de funciones. A continuación, se puede llamar a cada uno como esto:

ARGUMENTS = '()' 

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

Esto asume cada función tiene el mismo conjunto de argumentos definidos. Puede usar una instrucción if para detectar el nombre de la función enumerada por el usuario y proporcionar argumentos personalizados según lo que sea. También podría evaluar al leer el archivo python cuáles deberían ser los argumentos.

También podría verificar el objeto del módulo (supongo que es posible, no sé) ver si esa función existe antes de llamar al exec() o eval(). No sé, nuevamente, si uno puede evaluar desde el objeto de función qué argumentos toma. Sospecho que sí, pero esta es una pregunta separada (¿posiblemente ya respondida?).

+0

@Ninefingers, esto ayudaría, pero estoy en busca de importar funciones, no sólo los módulos. ¿Sabes cómo puedo lograr eso? – maroxe

+0

Supongo que __import__ es lo que estoy buscando – maroxe

+0

Sí y no. La instrucción de importación es un envolvente para las funciones de importación, por lo tanto, cuando se divierte import_module, * ha * importado un módulo variable * como si * hubiera pedido "importar alguna variable". No creo que puedas 'importar' nombres de variables pero puedes hacerlo a través de esta biblioteca. Ahora, una vez que haya importado un módulo, tendrá acceso a todo lo que contiene: amplié el ejemplo anterior para incluir el código que tiene acceso a 'INSTALLED_APPS' desde el archivo de configuración, como lo mencionó en la sección q. –

Cuestiones relacionadas