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
Pour vérifier si l'import peut trouver quelque chose dans python2, utilisez imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
Pour rechercher des importations pointillées, vous devez en 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 la même chose que la partie python3
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Vous devriez utiliser importlib
, voici comment je me suis débrouillé pour le faire:
import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None
Mon attente est, 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)
En Python3.4, importlib.find_loader
python docs était obsolète en faveur de importlib.util.find_spec
. La méthode recommandée est le importlib.util.find_spec
. Il en existe d'autres comme importlib.machinery.FileFinder
, utile si vous souhaitez charger un fichier spécifique. Comprendre comment les utiliser va au-delà de la portée de ceci.
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 également effectuer les opérations suivantes:
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 pour 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')
les commentaires sont les bienvenus pour résoudre ce problème
find_loader
Après avoir utilisé la réponse de yarbelk, j'ai créé ceci pour ne pas avoir à importer ìmp
.
try:
__import__('imp').find_module('eggs')
# Make things with supposed existing module
except ImportError:
pass
Utile dans settings.py
de Django par exemple.
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'une 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 ait 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 toute une série de retours en arrière pour déterminer que votre module existe et que la variable ImportError
est interceptée et provoque l'échec des choses en silence.
la réponse de go_as en une ligne
python -c "help('modules');" | grep module
Je suis tombé sur cette question alors que je cherchais un moyen de vérifier si un module est chargé à partir de la ligne de commande et voudrais partager mes pensées pour celles à venir. après moi et cherchant le même:
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 intégré système d'aide . (Cette fonction est destinée à une utilisation interactive .) Si aucun argument n'est fourni, 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 nom d'un module , fonction, classe, méthode, mot clé ou sujet 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 cet objet est générée.
Méthode interactive : chargement dans la console python
>>> help('module_name')
Si trouvé, quittez la lecture en tapant q
Pour quitter la session interactive python, appuyez sur Ctrl + D
Méthode du fichier de script Windows également compatible Linux/UNIX, et meilleur dans l'ensemble :
#!/usr/bin/env python
import sys
help(sys.argv[1])
L'appeler à partir de la commande comme:
python module_help.py site
Serait sortie:
Aide sur le site du module:
NAME
site - Ajoute les chemins de recherche de modules pour les packages tiers à sys.path.
FILE
/usr/lib/python2.7/site.py
MODULE DOCS
http://docs.python.org/library/site
DESCRIPTION
...
:
et vous devez appuyer sur q
pour quitter le mode interactif.
Utilisation de ce module inconnu:
python module_help.py lkajshdflkahsodf
Serait sortie:
no Python documentation trouvée pour 'lkajshdflkahsodf'
et sortir.
Utilisez l’un 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())
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 déclenché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)
afficherait un message ressemblant à No module named 'eggs'
si le module eggs
est introuvable; mais afficherait quelque chose comme No module named 'eggs.sub'
si seul le module sub
était introuvable, mais que le package eggs
soit également trouvé.
Voir le documentation du système d'importation pour plus d'informations sur le ModuleNotFoundError
Vous pouvez simplement écrire un petit script qui tente d'importer tous les modules et vous indique ceux qui échouent et ceux qui fonctionnent:
import pip
if __== '__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))
Sortie:
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
...
Mot d'avertissement cela va essayer d'importer tout donc vous verrez 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.
Une déclaration if plus simple de AskUbuntu: Comment vérifier si un module est installé en Python?
import sys
print('eggs' in sys.modules)
Vous pouvez également utiliser importlib
directement
import importlib
try:
importlib.import_module(module_name)
except ImportError:
# Handle error
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
Il n’existe aucun moyen de vérifier de manière fiable si un "module en pointillé" est importable sans importer son paquet parent. Cela dit, 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 selon lequel un module importé peut générer 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:
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