Como se faz o equivalente a “importação * de módulo” com a função __import__ do Python?

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

  •  02-07-2019
  •  | 
  •  

Pergunta

Dada uma string com um nome de módulo, como você importar tudo no módulo como se você tivesse chamado:

from module import *

i. determinada seqüência S = "módulo", como se obtém o equivalente ao seguinte:

__import__(S, fromlist="*")

Este não parece funcionar como esperado (como faz qualquer coisa não importar).

Foi útil?

Solução

Por favor, reconsidere. A única coisa pior do que import * é mágica import *.

Se você realmente quer:

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

Outras dicas

Aqui está a minha solução para nomeação dinâmica de arquivos de configurações locais para Django. Observe a adição abaixo de um cheque para não incluir atributos que contêm '__' do arquivo importado. O __name__ global estava sendo substituído com o nome do módulo do arquivo de configurações locais, o que causou setup_environ(), usado em manage.py, a ter 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)

O problema subjacente é que estou desenvolvendo alguns Django, mas em mais de um host (com colegas), todos com configurações diferentes. Eu estava esperando para fazer algo assim no arquivo de projeto / settings.py:

from platform import node

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

__import__( settings_files[ node() ] )

Parecia uma solução simples (assim elegante), mas eu concordo que ele tem um cheiro a ele ea simplicidade sai do loop quando você tem que usar a lógica como o que John Millikin postado (graças). Aqui está essencialmente a solução Fui com:

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

Que funciona bem para nossos propósitos.

Parece que você também pode usar dict.update () em dicionários do módulo no seu caso:

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

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

Update: Eu acho que há uma versão curta "funcional" do mesmo:

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

Eu não encontrei uma boa maneira de fazê-lo por isso, tomei uma maneira mais simples, mas feio 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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top