Necesito saber si existe un módulo de Python, sin importarlo.
Importar algo que podría no existir (no es lo que quiero):
try:
import eggs
except ImportError:
pass
Necesito saber si existe un módulo de Python, sin importarlo.
Importar algo que podría no existir (no es lo que quiero):
try:
import eggs
except ImportError:
pass
Respuestas:
Para verificar si la importación puede encontrar algo en python2, usando imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
Para encontrar importaciones punteadas, debe hacer más:
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
También puede usar pkgutil.find_loader
(más o menos lo mismo que la parte python3
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Deberías usar importlib
, Cómo hice esto fue:
import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None
Mi expectativa es que si puedes encontrar un cargador para él, entonces existe. También puede ser un poco más inteligente al respecto, como filtrar los cargadores que aceptará. Por ejemplo:
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)
En Python3.4, los importlib.find_loader
documentos de Python quedaron en desuso a favor de importlib.util.find_spec
. El método recomendado es el importlib.util.find_spec
. Hay otros como importlib.machinery.FileFinder
, lo que es útil si buscas un archivo específico para cargar. Descubrir cómo usarlos está más allá del alcance de esto.
import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None
Esto también funciona con importaciones relativas, pero debe proporcionar el paquete inicial, por lo que también podría hacer:
import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"
Si bien estoy seguro de que existe una razón para hacerlo, no estoy seguro de cuál sería.
¡Al intentar encontrar un submódulo, importará el módulo principal (para todos los métodos anteriores)!
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')
comentarios bienvenidos para evitar esto
find_loader
eggs.ham.spam
.
spam
en eggs.ham
ti imp.find_module('spam', ['eggs', 'ham'])
pkgutil.find_loader("my.package.module")
devuelve un cargador si el paquete / módulo existe y None
si no. Actualice su respuesta para Python 2, ya que enmascarar el ImportError me volvió loco ayer xP
Después de usar la respuesta de yarbelk, hice esto para no tener que importar ìmp
.
try:
__import__('imp').find_module('eggs')
# Make things with supposed existing module
except ImportError:
pass
Útil en Django settings.py
por ejemplo.
Se ModuleNotFoundError
ha introducido en Python 3.6 y se puede utilizar para este propósito.
try:
import eggs
except ModuleNotFoundError:
# Error handling
pass
El error se genera cuando no se puede encontrar un módulo o uno de sus padres . Entonces
try:
import eggs.sub
except ModuleNotFoundError as err:
# Error handling
print(err)
imprimiría un mensaje que se vería No module named 'eggs'
si el eggs
módulo no se puede encontrar; pero imprimiría algo como No module named 'eggs.sub'
si sub
no se pudiera encontrar el módulo pero se pudiera encontrar el eggs
paquete.
Consulte la documentación del sistema de importación para obtener más información sobreModuleNotFoundError
Hasta que se actualice la respuesta actual, este es el camino para Python 2
import pkgutil
import importlib
if pkgutil.find_loader(mod) is not None:
return importlib.import_module(mod)
return None
Muchas respuestas hacen uso de la captura de un ImportError
. El problema con eso es que no podemos saber qué arroja el ImportError
.
Si importa su loro módulo y sucede que hay una ImportError
en el módulo (por ejemplo, error tipográfico en la línea 1), el resultado será que el módulo no existe. Le llevará bastante retroceso descubrir que su módulo existe y que ImportError
está atrapado y hace que las cosas fallen silenciosamente.
ImportError
; edite si no le quedó claro.
La respuesta de go_as como un trazador de líneas
python -c "help('modules');" | grep module
Me encontré con esta pregunta mientras buscaba una forma de verificar si un módulo está cargado desde la línea de comandos y me gustaría compartir mis pensamientos sobre los que vienen después de mí y buscan lo mismo:
Método de archivo de script Linux / UNIX : cree un archivo module_help.py
:
#!/usr/bin/env python
help('modules')
Luego asegúrese de que sea ejecutable: chmod u+x module_help.py
Y llámalo con un pipe
para grep
:
./module_help.py | grep module_name
Invoque el sistema de ayuda incorporado . (Esta función está destinada para uso interactivo .) Si no se proporciona ningún argumento, el sistema de ayuda interactivo se inicia en la consola del intérprete. Si el argumento es una cadena , se busca la cadena como el nombre de un módulo , función, clase, método, palabra clave o tema de documentación, y se imprime una página de ayuda en la consola. Si el argumento es cualquier otro tipo de objeto, se genera una página de ayuda sobre el objeto.
Método interactivo : en la carga de la consolapython
>>> help('module_name')
Si se encuentra, deje de leer escribiendo q
Para salir de la sesión interactiva de Python, presione Ctrl+D
El método de archivo de script de Windows también es compatible con Linux / UNIX, y mejor en general :
#!/usr/bin/env python
import sys
help(sys.argv[1])
Llamándolo desde el comando como:
python module_help.py site
Daría salida:
Ayuda en el sitio del módulo:
NAME
sitio: agregue rutas de búsqueda de módulos para paquetes de terceros a sys.path.
FILE
/usr/lib/python2.7/site.py
MODULE DOCS
http://docs.python.org/library/site
DESCRIPTION
...
:
y tendrías que presionar q
para salir del modo interactivo.
Utilizándolo módulo desconocido:
python module_help.py lkajshdflkahsodf
Daría salida:
no se encontró documentación de Python para 'lkajshdflkahsodf'
y salir
Utilice una de las funciones de pkgutil , por ejemplo:
from pkgutil import iter_modules
def module_exists(module_name):
return module_name in (name for loader, name, ispkg in iter_modules())
Una declaración if más simple de AskUbuntu: ¿Cómo verifico si un módulo está instalado en Python?
import sys
print('eggs' in sys.modules)
Puede escribir un pequeño script que intente importar todos los módulos y decirle cuáles fallan y cuáles funcionan:
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))
Salida:
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
...
Una advertencia: esto intentará importar todo para que veas cosas como PyYAML failed with error code: No module named pyyaml
porque el nombre de importación real es solo yaml. Entonces, siempre que conozca sus importaciones, esto debería ser el truco para usted.
Escribí esta función 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
También puedes usar importlib
directamente
import importlib
try:
importlib.import_module(module_name)
except ImportError:
# Handle error
No hay forma de verificar de manera confiable si el "módulo de puntos" es importable sin importar su paquete principal. Dicho esto, hay muchas soluciones al problema "cómo verificar si existe el módulo Python".
La solución a continuación soluciona el problema de que el módulo importado puede generar ImportError incluso si existe. Queremos distinguir esa situación de aquella en la que el módulo no 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
en 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