Pergunta

Eu estou tentando carregar módulos dinamicamente que eu criei.

Agora isso funciona corretamente:

import structures.index

Mas se eu tentar a mesma coisa por importá-lo dinamicamente, ele falhar.

struct = __import__("structures.index")

Erro fornecido é:

Error ('No module named structures.index',)

Todas as ideias por quê?


Edit: Ao usar escopo completo (que tipo de obras?):

struct = __import__("neoform.structures.index")

Esta não lançar quaisquer erros, no entanto, não está a carregar o módulo de índice, que é carregar o módulo "Neoform" em vez.

O resultado da "estrutura" é:

<module 'neoform' from '/neoform/__init__.py'>

Além disso, como uma questão de lado, como posso então instanciar uma classe dentro de um módulo carregado dinamicamente? (Assumindo que todos os módulos contêm um nome de classe comum).

Edit: Solução: (graças coonj & Rick) Isto acabou sendo o que funcionou. Não sei por que (ainda), mas o fromlist tinha que ser algo "aparentemente nada, uma vez que trabalhou quando eu coloco a letra 'a' como um valor (estranho, dado que o arquivo só tinha 1 classe nele).

def get_struct_module(self, name):
    try:
        return = __import__("neoform.structures." + name, fromlist='*')
    except ImportError, e:
        self.out.add("Could not load struct: neoform.structure." + name + "\n\n" + "Error " + str(e.args))
Foi útil?

Solução

Eu não tenho certeza do que "falhar" significa, por isso vou apenas mencionar que __import__('structures.index') deve, de fato, o trabalho, mas não atribui o nome do módulo no escopo atual. Para fazer isso (e, em seguida, usar uma classe no módulo importado dinamicamente), você terá que usar:

structures = __import__('structures.index')
structures.index.SomeClass(...)

Os detalhes completos sobre __import__ estão disponíveis aqui .

Editar: (baseado na pergunta edit)

Para neoform.structures.index importação, e retornar o módulo index, você faria o seguinte:

structures = __import__('neoform.structures.index', 
                        fromlist=['does not in fact matter what goes here!'])

Então, se você tem uma lista de nomes de pacotes packages, você pode importar seus módulos index e instanciar uma classe MyClass para cada usando o seguinte código:

modules = [ __import__('neoform.%s.index' % pkg, fromlist=['a']) 
            for pkg in packages ]
objects = [ m.MyClass() for m in modules ]

Outras dicas

Para importar sub-módulos, é preciso especificá-los na arg fromlist de __import__()
Fo exemplo, o equivalente a:

import structures.index

é:

structures = __import__('structures', fromlist=['index'])

Para fazer isso em um mapa é um pouco mais complicado ...

import mod1.index
import mod2.index
import mod3.index

Para as importações, que você gostaria de definir uma nova função para obter o sub-módulo index de cada módulo:

def getIndexMods(mod_names):
  mod_list = map(lambda x: __import__(x, fromlist='index'))
  index_mods = [mod.index for mod in mod_list]
  return index_mods

Agora, você pode fazer isso para obter referências a todos os módulos do índice:

index_mods = getIndexMods(['mod1', 'mod2', 'mod3'])

Além disso, se você quiser sub-módulos de apoio que não são nomeadas 'index', então você poderia fazer isso:

mod1, mod2, mod3 = map(lambda x,y: __import__(x, fromlist=y), 
  ['mod1', 'mod2', 'mod3'], ['index1', 'index2', 'index3'])

Use escopo completo ( "neoform.structures.index") com este método auxiliar.

def import_module(name):
    mod = __import__(name)
    components = name.split('.')
    for comp in components[1:]:
        mod = getattr(mod, comp)
    return mod

module = import_module("neoform.structures.index")
# do stuff with module

programador Java aqui, mas eu acho que você precisa imp módulo

>>> import imp
>>> fm = imp.find_module('index', ['./structures']) # for submodule
>>> mymod = imp.load_module('structures.index', *fm)
>>> mymod
<module 'structures.index' from './structures/index.pyc'>
>>> x = mymod.insideIndex()
Initialising index class...

Voila!

Por que diabos você substituir

import structures.index

com

map(__import__, ["structures.index"])

O primeiro (a) obras, (b) é dinâmico e (c) é suportado diretamente. Que possível caso de uso está lá para substituir fácil de mudança, fonte de texto simples com algo mais complexo?

Em suma: não faça isso. Ele não tem qualquer valor.


Editar

O "Eu estou recebendo a importação a partir de um banco de dados" é um esforço nobre, mas ainda não é sensato. O bloco de código depende de essas importações? Esse bloco de código inteiro - importações e todos - é o que você deseja executar. Esse bloco de código inteiro - importação, declarações e tudo -. Deve ser um simples arquivo de módulo python de idade

Import que bloco de código do sistema de arquivos. Use o banco de dados para identificar qual arquivo, o autor do arquivo - qualquer coisa que você quiser usar o banco de dados para. Mas simplesmente importar e executar o módulo da forma mais simples possível.

Realmente tarde postar aqui. Mas eu estava procurando por esta pergunta no google. Eu fiz alguma tentativa e erro. Não tenho certeza se este trecho vai ajudar, mas aqui está. Usá-lo para o local Flask.

modules = ['frontend', 'admin']
for module in modules:
    mod = __init__('controllers.%s' % module, fromlist=[module])
    app.register_blueprint(mod.blueprint_mod)


# or
from importlib import import_module
modules = ['frontend', 'admin']
for module in modules:
    mod = import_module('controllers.%s' % module)
    app.regitster_blueprint(mod.blueprint_mod)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top