2010-11-07 23 views
19

Tengo un módulo de Python que deseo importar dinámicamente dado solo una cadena del nombre del módulo. Normalmente uso importlib o __import__ y esto funciona bastante bien dado que sé qué objetos quiero importar desde el módulo, pero ¿hay alguna manera de hacer el equivalente de import * dinámicamente? ¿O hay un mejor enfoque?Importación de todo (*) dinámicamente desde un módulo

Sé, en general, que es una mala práctica usar import *, pero los módulos que intento importar se generan automáticamente sobre la marcha y no tengo forma de conocer el módulo exacto que contiene la clase que estoy tratando.

Gracias.

+0

Así, mientras que hay maneras de hacer este trabajo, al igual que @GWW enumerados - no sería una buena cosa que hacer. Deberías considerar asignar el módulo importado con __import__ a un nombre, y usar "getattr" e incluso la sintaxis de puntos para acceder a sus miembros. – jsbueno

Respuesta

5

Me salió un feo código hacky, funciona en python 2.6. No estoy seguro si esto es lo más inteligente que hacer sin embargo, tal vez algunas otras personas aquí tienen una idea:

test = __import__('os',globals(),locals()) 
for k in dir(test): 
    globals()[k] = test.__dict__[k] 

Es posible que desee poner un cheque aquí para asegurarse de que no va a sobrescribir nada en el espacio de nombres global. Probablemente puedas evitar la parte global y solo mirar a través de cada módulo importado dinámicamente para tu clase de interés. Esto probablemente sería mucho mejor que contaminar el espacio de nombres global con todo lo que está importando.

Por ejemplo, digamos que su clase se denomina Solicitud de urllib2

test = __import__('urllib2',globals(),locals()) 
cls = None 
if 'Request' in dir(test): 
    cls = test.__dict__['Request'] 
    # you found the class now you can use it! 
    cls('http://test.com') 
+0

Lo que sugiero que hagas es buscar en los contenidos de cada uno de esos módulos "generados" por el nombre de clase de interés. Supongo que al menos sabes el nombre de la clase que estás buscando. Edité mi respuesta para darte un ejemplo. – GWW

+2

En realidad, esto es menos hackish de lo que yoyu pueda pensar: tiene exactamente el mismo efecto que "de import *" - como lo que hace esta declaración es actualizar el diccionario actual de globals. Este es el mismo diccionario recuperado por una llamada a globals(). En cuanto a los "controles", advierte al OP acerca de: tenga en cuenta que "importar *" simplemente sobrescribe todo :-) – jsbueno

+0

Supongo que no es tan malo. Creo que siempre siento que hay una forma "más elegante" de hacer cosas en Python. – GWW

0

La única forma en que puedo pensar en hacer esto es usar exec() y generar dinámicamente el comando importlib sobre la marcha.

+1

Como puede ver, hay mejores formas. – jsbueno

+2

Sí, ahora puedo ver :) – g19fanatic

20

Uso update para dicts:

globals().update(importlib.import_module('some.package').__dict__) 

Tenga en cuenta, que el uso de a_module.__dict__ no es lo mismo que from a_module import *, porque todos los nombres son "importado", no solo aquellos de __all__ o no comenzando con _.

+4

Esto es ligeramente mejor que la respuesta de GWW, ya que utiliza la actualización en lugar de una iteración sobre el módulo. –

2

El siguiente es altamente pecaminoso y le condenan al purgatorio o peor

# module A 
myvar = "hello" 

# module B 
import inspect 
def dyn_import_all(modpath): 
    """Incredibly hackish way to load into caller's global namespace""" 
    exec('from ' + modpath + ' import *', inspect.stack()[1][0].f_globals) 

# module C 
from module B import dyn_import_all 
def print_from(modpath): 
    dyn_import_all(modpath) 
    print(myvar) 
+1

olvidó 'os.system ('rm -rf ....' al final allí .. – gauteh

Cuestiones relacionadas