Pergunta

Em tempo de execução, o código Python recebe o nome de um submódulo para carregar, que não conheço antes.Agora, quero verificar se este submódulo existe dentro de um módulo existente.Considere esta estrutura, onde foo e bar pode ser especificado:

master/
|
|- __init__.py
|
|- foo/
|  |
|  |- __init__.py
|
|- bar/
   |
   |- __init__.py

Agora, normalmente eu faço isso, o que funciona para defs e variáveis:

import master

unknown_submodule = "foo"
if hasattr(master, unknown_submodule):
    pass # all's well

ou estou pegando o AttributeError, que funciona igualmente.

No entanto, com a estrutura de arquivos acima, não consigo colocar essa abordagem em funcionamento. hasattr() retorna sempre False (ou seja, sempre há um AttributeError lançado).

Se eu olhar dir(master), vejo esta saída:

['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

e até mesmo especificando explicitamente __all__ em master/__init__.py não ajuda, mas altera dir() para

['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

Alguma ideia do que estou fazendo de errado ou se existe uma maneira de realizar esse tipo de teste?(Por falar nisso:Python 2.6 no Win/Cygwin, se isso for de algum interesse)

Foi útil?

Solução

Os submódulos não são atributos de seus módulos pais, a menos que sejam explicitamente declarados.Simplesmente tente importar o módulo e capturar ImportError:

try:
    __import__("os.peth", fromlist=[os])
except ImportError:
    pass

Outras dicas

você pode fazer

try:
 import module.submodule

except ImportError:
  print 'failed or whatever'

Recentemente tive que verificar a existência do submódulo e como estou usando o python 3.4.1, estou dando uma nova resposta para a pergunta:

No python 3.4.1 você pode usar importlib.util.find_spec(name, package=None) (https://docs.python.org/3.4/library/importlib.html#importlib.util.find_spec)

import importlib
module_exists = importlib.util.find_spec('path.to.my.module')

Tão fácil =)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top