J'ai besoin de savoir si un module python existe, sans l'importer.
Importer quelque chose qui pourrait ne pas exister (pas ce que je veux):
try:
import eggs
except ImportError:
pass
J'ai besoin de savoir si un module python existe, sans l'importer.
Importer quelque chose qui pourrait ne pas exister (pas ce que je veux):
try:
import eggs
except ImportError:
pass
Réponses:
Pour vérifier si l'importation peut trouver quelque chose dans python2, utilisez imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
Pour trouver des importations pointées, vous devez faire plus:
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
Vous pouvez également utiliser pkgutil.find_loader
(plus ou moins le même que la partie python3
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Vous devriez utiliser importlib
, Comment j'ai fait cela était:
import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None
Mon attente étant, si vous pouvez trouver un chargeur pour cela, alors il existe. Vous pouvez également être un peu plus intelligent à ce sujet, comme filtrer les chargeurs que vous accepterez. Par exemple:
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)
Dans Python3.4, la importlib.find_loader
documentation python était obsolète au profit de importlib.util.find_spec
. La méthode recommandée est la importlib.util.find_spec
. Il y en a d'autres comme importlib.machinery.FileFinder
, ce qui est utile si vous recherchez un fichier spécifique à charger. Comprendre comment les utiliser dépasse le cadre de cela.
import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None
Cela fonctionne également avec les importations relatives, mais vous devez fournir le package de départ, vous pouvez donc également faire:
import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"
Bien que je sois sûr qu'il existe une raison de faire cela, je ne suis pas sûr de ce que ce serait.
Lorsque vous essayez de trouver un sous-module, il importera le module parent (pour toutes les méthodes ci-dessus)!
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')
commentaires bienvenus pour contourner ce problème
find_loader
eggs.ham.spam
.
spam
en eggs.ham
vous utiliseriezimp.find_module('spam', ['eggs', 'ham'])
pkgutil.find_loader("my.package.module")
retourne un chargeur si le package / module existe et None
sinon. Veuillez mettre à jour votre réponse pour Python 2, car le masquage de l'ImportError m'a rendu fou hier xP
Après avoir utilisé la réponse de yarbelk, je l'ai fait pour ne pas avoir à importer ìmp
.
try:
__import__('imp').find_module('eggs')
# Make things with supposed existing module
except ImportError:
pass
Utile dans Django settings.py
par exemple.
Le ModuleNotFoundError
a été introduit dans python 3.6 et peut être utilisé à cette fin
try:
import eggs
except ModuleNotFoundError:
# Error handling
pass
L'erreur est générée lorsqu'un module ou l'un de ses parents est introuvable. Alors
try:
import eggs.sub
except ModuleNotFoundError as err:
# Error handling
print(err)
affichera un message qui ressemble à No module named 'eggs'
si le eggs
module est introuvable; mais afficherait quelque chose comme No module named 'eggs.sub'
si seul le sub
module ne pouvait pas être trouvé mais que le eggs
paquet pouvait être trouvé.
Consultez la documentation du système d'importation pour plus d'informations sur leModuleNotFoundError
Jusqu'à ce que la réponse actuelle soit mise à jour, voici le chemin pour Python 2
import pkgutil
import importlib
if pkgutil.find_loader(mod) is not None:
return importlib.import_module(mod)
return None
Beaucoup de réponses utilisent la capture d'un fichier ImportError
. Le problème avec cela est que nous ne pouvons pas savoir ce qui jette le ImportError
.
Si vous importez votre module existant et qu'il se trouve qu'il y en a un ImportError
dans votre module (par exemple une faute de frappe sur la ligne 1), le résultat sera que votre module n'existe pas. Il vous faudra beaucoup de retour en arrière pour comprendre que votre module existe et qu'il ImportError
est intercepté et fait échouer les choses en silence.
ImportError
- veuillez modifier si cela ne vous était pas clair.
La réponse de go_as en une seule ligne
python -c "help('modules');" | grep module
Je suis tombé sur cette question en cherchant un moyen de vérifier si un module est chargé à partir de la ligne de commande et j'aimerais partager mes réflexions sur ceux qui viennent après moi et à la recherche de la même chose:
Méthode de fichier de script Linux / UNIX : créer un fichier module_help.py
:
#!/usr/bin/env python
help('modules')
Ensuite, assurez-vous qu'il est exécutable: chmod u+x module_help.py
Et appelez-le avec un pipe
à grep
:
./module_help.py | grep module_name
Appelez le système d'aide intégré . (Cette fonction est destinée à une utilisation interactive .) Si aucun argument n'est donné, le système d'aide interactif démarre sur la console d'interprétation. Si l'argument est une chaîne , la chaîne est recherchée comme le nom d'un module , d'une fonction, d'une classe, d'une méthode, d'un mot-clé ou d'une rubrique de documentation, et une page d'aide est imprimée sur la console. Si l'argument est un autre type d'objet, une page d'aide sur l'objet est générée.
Méthode interactive : dans le chargement de la consolepython
>>> help('module_name')
Si trouvé, quittez la lecture en tapant q
Pour quitter la session interactive python, appuyez sur Ctrl+D
Méthode de fichier de script Windows également compatible Linux / UNIX, et meilleure dans l'ensemble :
#!/usr/bin/env python
import sys
help(sys.argv[1])
L'appel à partir de la commande comme:
python module_help.py site
Produirait:
Aide sur le site du module:
NAME
site - Ajoutez les chemins de recherche de module pour les packages tiers à sys.path.
FILE
/usr/lib/python2.7/site.py
MODULE DOCS
http://docs.python.org/library/site
DESCRIPTION
...
:
et vous devrez appuyer sur q
pour quitter le mode interactif.
En utilisant ce module inconnu:
python module_help.py lkajshdflkahsodf
Produirait:
aucune documentation Python trouvée pour 'lkajshdflkahsodf'
et sortir.
Utilisez l'une des fonctions de pkgutil , par exemple:
from pkgutil import iter_modules
def module_exists(module_name):
return module_name in (name for loader, name, ispkg in iter_modules())
Une instruction if plus simple d'AskUbuntu: Comment vérifier si un module est installé en Python?
import sys
print('eggs' in sys.modules)
Vous pouvez simplement écrire un petit script qui essaierait d'importer tous les modules et vous dirait lesquels échouent et lesquels fonctionnent:
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))
Production:
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
...
Parole d'avertissement, cela essaiera de tout importer pour que vous voyiez des choses comme PyYAML failed with error code: No module named pyyaml
parce que le nom d'importation réel est juste yaml. Donc, tant que vous connaissez vos importations, cela devrait faire l'affaire pour vous.
J'ai écrit cette fonction d'assistance:
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
Vous pouvez également utiliser importlib
directement
import importlib
try:
importlib.import_module(module_name)
except ImportError:
# Handle error
Il n'y a aucun moyen de vérifier de manière fiable si le "module pointillé" est importable sans importer son package parent. En disant cela, il existe de nombreuses solutions au problème "comment vérifier si le module Python existe".
La solution ci-dessous résout le problème que le module importé peut soulever ImportError même s'il existe. Nous voulons distinguer cette situation de celle dans laquelle le module n'existe pas.
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
dans 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