¿Cómo se hace el equivalente de "importar * desde el módulo" con la función __import__ de Python?

StackOverflow https://stackoverflow.com/questions/147507

  •  02-07-2019
  •  | 
  •  

Pregunta

Dada una cadena con un nombre de módulo, ¿cómo importa todo en el módulo como si hubiera llamado?

from module import *

es decir cadena dada S = " módulo " ;, cómo se obtiene el equivalente de lo siguiente:

__import__(S, fromlist="*")

Esto no parece funcionar como se esperaba (ya que no importa nada).

¿Fue útil?

Solución

Por favor, reconsidere. Lo único peor que import * es magic import * .

Si realmente quieres:

m = __import__ (S)
try:
    attrlist = m.__all__
except AttributeError:
    attrlist = dir (m)
for attr in attrlist:
    globals()[attr] = getattr (m, attr)

Otros consejos

Aquí está mi solución para la asignación dinámica de nombres de archivos de configuración local para Django. Tenga en cuenta la adición a continuación de una verificación para no incluir atributos que contengan '__' del archivo importado. El global __name__ se estaba sobrescribiendo con el nombre del módulo del archivo de configuración local, lo que causó que setup_environ () , utilizado en manage.py, tenga problemas.

try:
    import socket
    HOSTNAME = socket.gethostname().replace('.','_')
    # See http://docs.python.org/library/functions.html#__import__
    m = __import__(name="settings_%s" % HOSTNAME, globals=globals(), locals=locals(), fromlist="*")
    try:
        attrlist = m.__all__
    except AttributeError:
        attrlist = dir(m)        
    for attr in [a for a in attrlist if '__' not in a]:
        globals()[attr] = getattr(m, attr)

except ImportError, e:
    sys.stderr.write('Unable to read settings_%s.py\n' % HOSTNAME)
    sys.exit(1)

El problema subyacente es que estoy desarrollando algunos Django, pero en más de un host (con colegas), todos con diferentes configuraciones. Esperaba hacer algo como esto en el archivo project / settings.py:

from platform import node

settings_files = { 'BMH.lan': 'settings_bmh.py", ... } 

__import__( settings_files[ node() ] )

Parecía una solución simple (por lo tanto elegante), pero estoy de acuerdo en que tiene un olor y la simplicidad se desvanece cuando tienes que usar la lógica como la que publicó John Millikin (gracias). Esta es esencialmente la solución con la que fui:

from platform import node

from settings_global import *

n = node()

if n == 'BMH.lan':
  from settings_bmh import *
# add your own, here...
else:
  raise Exception("No host settings for '%s'. See settings.py." % node())

Lo que funciona bien para nuestros propósitos.

Parece que también puede usar dict.update () en los diccionarios del módulo en su caso:

config = [__import__(name) for name in names_list]

options = {}
for conf in config:
    options.update(conf.__dict__)

Actualización: Creo que hay un breve " funcional " versión del mismo:

options = reduce(dict.update, map(__import__, names_list))

No encontré una buena manera de hacerlo, así que tomé una forma más simple pero fea de http://www.djangosnippets.org/snippets/600/

try:
    import socket
    hostname = socket.gethostname().replace('.','_')
    exec "from host_settings.%s import *" % hostname
except ImportError, e:
    raise e
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top