Eu preciso saber se existe um módulo python, sem importá-lo.
Importando algo que pode não existir (não o que eu quero):
try:
import eggs
except ImportError:
pass
Eu preciso saber se existe um módulo python, sem importá-lo.
Importando algo que pode não existir (não o que eu quero):
try:
import eggs
except ImportError:
pass
Respostas:
Para verificar se a importação pode encontrar algo no python2, use imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
Para encontrar importações pontilhadas, você precisa fazer mais:
import imp
try:
spam_info = imp.find_module('spam')
spam = imp.load_module('spam', *spam_info)
imp.find_module('eggs', spam.__path__) # __path__ is already a list
found = True
except ImportError:
found = False
Você também pode usar pkgutil.find_loader
(mais ou menos o mesmo que a parte python3
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Você deve usar importlib
, como eu fiz isso foi:
import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None
Minha expectativa é que, se você puder encontrar um carregador para ele, ele existe. Você também pode ser um pouco mais inteligente, como filtrar quais carregadores você aceitará. Por exemplo:
import importlib
spam_loader = importlib.find_loader('spam')
# only accept it as valid if there is a source file for the module - no bytecode only.
found = issubclass(type(spam_loader), importlib.machinery.SourceFileLoader)
No Python3.4, os importlib.find_loader
documentos python foram preteridos em favor de importlib.util.find_spec
. O método recomendado é o importlib.util.find_spec
. Existem outros como importlib.machinery.FileFinder
, o que é útil se você estiver atrás de um arquivo específico para carregar. Descobrir como usá-los está além do escopo disso.
import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None
Isso também funciona com importações relativas, mas você deve fornecer o pacote inicial, para que você também possa:
import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"
Embora tenha certeza de que existe uma razão para fazer isso - não tenho certeza do que seria.
Ao tentar encontrar um submódulo, ele importará o módulo pai (para todos os métodos acima)!
food/
|- __init__.py
|- eggs.py
## __init__.py
print("module food loaded")
## eggs.py
print("module eggs")
were you then to run
>>> import importlib
>>> spam_spec = importlib.find_spec("food.eggs")
module food loaded
ModuleSpec(name='food.eggs', loader=<_frozen_importlib.SourceFileLoader object at 0x10221df28>, origin='/home/user/food/eggs.py')
comentários bem-vindos em contornar este
find_loader
eggs.ham.spam
.
spam
em eggs.ham
você usariaimp.find_module('spam', ['eggs', 'ham'])
pkgutil.find_loader("my.package.module")
retorna um carregador se o pacote / módulo existir e None
se não existir . Atualize sua resposta para o Python 2, pois mascarar o ImportError me deixou louco ontem xP
Depois de usar a resposta do yarbelk, fiz isso para não precisar importar ìmp
.
try:
__import__('imp').find_module('eggs')
# Make things with supposed existing module
except ImportError:
pass
Útil no Django, settings.py
por exemplo.
O ModuleNotFoundError
foi introduzido no python 3.6 e pode ser usado para essa finalidade
try:
import eggs
except ModuleNotFoundError:
# Error handling
pass
O erro ocorre quando um módulo ou um de seus pais não pode ser encontrado. assim
try:
import eggs.sub
except ModuleNotFoundError as err:
# Error handling
print(err)
imprimiria uma mensagem parecida com No module named 'eggs'
aeggs
módulo não pode ser encontrado; mas imprimiria algo como No module named 'eggs.sub'
se apenas o sub
módulo não pudesse ser encontrado, mas o eggs
pacote pudesse ser encontrado.
Consulte a documentação do sistema de importação para obter mais informações sobre oModuleNotFoundError
Até que a resposta atual seja atualizada, aqui está o caminho para o Python 2
import pkgutil
import importlib
if pkgutil.find_loader(mod) is not None:
return importlib.import_module(mod)
return None
Muitas respostas fazem uso de pegar um ImportError
. O problema disso é que não podemos saber o que lança oImportError
.
Se você importar seu módulo existente e houver um ImportError
no seu módulo (por exemplo, erro de digitação na linha 1), o resultado será que seu módulo não existe. Você precisará de uma grande quantidade de retorno para descobrir que o seu módulo existe e ImportError
é capturado e faz com que as coisas falhem silenciosamente.
ImportError
- edite se não estiver claro para você.
A resposta de go_as como um forro
python -c "help('modules');" | grep module
Me deparei com essa pergunta enquanto procurava uma maneira de verificar se um módulo está carregado na linha de comando e gostaria de compartilhar meus pensamentos para os que vieram depois de mim e procurando o mesmo:
Método de arquivo de script Linux / UNIX : make a file module_help.py
:
#!/usr/bin/env python
help('modules')
Em seguida, verifique se é executável: chmod u+x module_help.py
E chame-o com a pipe
para grep
:
./module_help.py | grep module_name
Chame o sistema de ajuda interno . (Esta função é destinada ao uso interativo .) Se nenhum argumento for fornecido, o sistema de ajuda interativo será iniciado no console do intérprete. Se o argumento for uma sequência , ela será procurada como o nome de um módulo , função, classe, método, palavra-chave ou tópico da documentação, e uma página de ajuda será impressa no console. Se o argumento for qualquer outro tipo de objeto, uma página de ajuda no objeto será gerada.
Método interativo : na carga do consolepython
>>> help('module_name')
Se encontrado, saia da leitura digitando q
Para sair da sessão interativa python, pressione Ctrl+D
O método de arquivo de script do Windows também é compatível com Linux / UNIX e , em geral , melhor :
#!/usr/bin/env python
import sys
help(sys.argv[1])
Chamando a partir do comando, como:
python module_help.py site
Saída:
Ajuda no site do módulo:
NAME
site - Anexe caminhos de pesquisa do módulo para pacotes de terceiros no sys.path.
FILE
/usr/lib/python2.7/site.py
MODULE DOCS
http://docs.python.org/library/site
DESCRIPTION
...
:
e você teria que pressionar q
para sair do modo interativo.
Usando-o módulo desconhecido:
python module_help.py lkajshdflkahsodf
Saída:
nenhuma documentação Python encontrada para 'lkajshdflkahsodf'
e saia.
Use uma das funções do pkgutil , por exemplo:
from pkgutil import iter_modules
def module_exists(module_name):
return module_name in (name for loader, name, ispkg in iter_modules())
Uma declaração if mais simples do AskUbuntu: Como verifico se um módulo está instalado no Python?
import sys
print('eggs' in sys.modules)
Você pode escrever um pequeno script que tentará importar todos os módulos e informar quais estão falhando e quais estão funcionando:
import pip
if __name__ == '__main__':
for package in pip.get_installed_distributions():
pack_string = str(package).split(" ")[0]
try:
if __import__(pack_string.lower()):
print(pack_string + " loaded successfully")
except Exception as e:
print(pack_string + " failed with error code: {}".format(e))
Resultado:
zope.interface loaded successfully
zope.deprecation loaded successfully
yarg loaded successfully
xlrd loaded successfully
WMI loaded successfully
Werkzeug loaded successfully
WebOb loaded successfully
virtualenv loaded successfully
...
Aviso: isso tentará importar tudo, assim você verá coisas como PyYAML failed with error code: No module named pyyaml
porque o nome da importação real é apenas yaml. Portanto, desde que você conheça suas importações, isso deve fazer o truque para você.
Eu escrevi esta função auxiliar:
def is_module_available(module_name):
if sys.version_info < (3, 0):
# python 2
import importlib
torch_loader = importlib.find_loader(module_name)
elif sys.version_info <= (3, 3):
# python 3.0 to 3.3
import pkgutil
torch_loader = pkgutil.find_loader(module_name)
elif sys.version_info >= (3, 4):
# python 3.4 and above
import importlib
torch_loader = importlib.util.find_spec(module_name)
return torch_loader is not None
Você também pode usar importlib
diretamente
import importlib
try:
importlib.import_module(module_name)
except ImportError:
# Handle error
Não há como verificar com segurança se o "módulo pontilhado" é importável sem importar o pacote pai. Dizendo isso, existem muitas soluções para o problema "como verificar se o módulo Python existe".
A solução abaixo aborda o problema que o módulo importado pode gerar ImportError mesmo que ele exista. Queremos distinguir essa situação daquela em que módulo não existe.
Python 2 :
import importlib
import pkgutil
import sys
def find_module(full_module_name):
"""
Returns module object if module `full_module_name` can be imported.
Returns None if module does not exist.
Exception is raised if (existing) module raises exception during its import.
"""
module = sys.modules.get(full_module_name)
if module is None:
module_path_tail = full_module_name.split('.')
module_path_head = []
loader = True
while module_path_tail and loader:
module_path_head.append(module_path_tail.pop(0))
module_name = ".".join(module_path_head)
loader = bool(pkgutil.find_loader(module_name))
if not loader:
# Double check if module realy does not exist
# (case: full_module_name == 'paste.deploy')
try:
importlib.import_module(module_name)
except ImportError:
pass
else:
loader = True
if loader:
module = importlib.import_module(full_module_name)
return module
Python 3 :
import importlib
def find_module(full_module_name):
"""
Returns module object if module `full_module_name` can be imported.
Returns None if module does not exist.
Exception is raised if (existing) module raises exception during its import.
"""
try:
return importlib.import_module(full_module_name)
except ImportError as exc:
if not (full_module_name + '.').startswith(exc.name + '.'):
raise
no django.utils.module_loading.module_has_submodule
import sys
import os
import imp
def module_has_submodule(package, module_name):
"""
check module in package
django.utils.module_loading.module_has_submodule
"""
name = ".".join([package.__name__, module_name])
try:
# None indicates a cached miss; see mark_miss() in Python/import.c.
return sys.modules[name] is not None
except KeyError:
pass
try:
package_path = package.__path__ # No __path__, then not a package.
except AttributeError:
# Since the remainder of this function assumes that we're dealing with
# a package (module with a __path__), so if it's not, then bail here.
return False
for finder in sys.meta_path:
if finder.find_module(name, package_path):
return True
for entry in package_path:
try:
# Try the cached finder.
finder = sys.path_importer_cache[entry]
if finder is None:
# Implicit import machinery should be used.
try:
file_, _, _ = imp.find_module(module_name, [entry])
if file_:
file_.close()
return True
except ImportError:
continue
# Else see if the finder knows of a loader.
elif finder.find_module(name):
return True
else:
continue
except KeyError:
# No cached finder, so try and make one.
for hook in sys.path_hooks:
try:
finder = hook(entry)
# XXX Could cache in sys.path_importer_cache
if finder.find_module(name):
return True
else:
# Once a finder is found, stop the search.
break
except ImportError:
# Continue the search for a finder.
continue
else:
# No finder found.
# Try the implicit import machinery if searching a directory.
if os.path.isdir(entry):
try:
file_, _, _ = imp.find_module(module_name, [entry])
if file_:
file_.close()
return True
except ImportError:
pass
# XXX Could insert None or NullImporter
else:
# Exhausted the search, so the module cannot be found.
return False