Como verificar submódulos em Python com hasattr
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)
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 =)