Devo sapere se esiste un modulo Python, senza importarlo.
Importare qualcosa che potrebbe non esistere (non quello che voglio):
try:
import eggs
except ImportError:
pass
Devo sapere se esiste un modulo Python, senza importarlo.
Importare qualcosa che potrebbe non esistere (non quello che voglio):
try:
import eggs
except ImportError:
pass
Risposte:
Per verificare se l'importazione può trovare qualcosa in python2, usando imp
import imp
try:
imp.find_module('eggs')
found = True
except ImportError:
found = False
Per trovare le importazioni punteggiate, devi fare di più:
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
Puoi anche usare pkgutil.find_loader
(più o meno lo stesso della parte python3
import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None
Dovresti usare importlib
, Come ho fatto per fare questo è stato:
import importlib
spam_loader = importlib.find_loader('spam')
found = spam_loader is not None
La mia aspettativa è, se riesci a trovare un caricatore per esso, allora esiste. Puoi anche essere un po 'più intelligente a riguardo, come filtrare quali caricatori accetterai. Per esempio:
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)
In Python3.4 i importlib.find_loader
documenti di Python sono stati deprecati a favore di importlib.util.find_spec
. Il metodo raccomandato è il importlib.util.find_spec
. Ce ne sono altri simili importlib.machinery.FileFinder
, utili se si desidera caricare un file specifico. Capire come usarli è oltre lo scopo di questo.
import importlib
spam_spec = importlib.util.find_spec("spam")
found = spam_spec is not None
Questo funziona anche con le importazioni relative ma è necessario fornire il pacchetto iniziale, quindi è possibile anche:
import importlib
spam_spec = importlib.util.find_spec("..spam", package="eggs.bar")
found = spam_spec is not None
spam_spec.name == "eggs.spam"
Anche se sono sicuro che esiste una ragione per farlo - non sono sicuro di cosa sarebbe.
Quando si cerca di trovare un sottomodulo, importerà il modulo genitore (per tutti i metodi sopra)!
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')
commenti benvenuti su come aggirare questo
find_loader
eggs.ham.spam
.
spam
in eggs.ham
useresteimp.find_module('spam', ['eggs', 'ham'])
pkgutil.find_loader("my.package.module")
restituisce un caricatore se il pacchetto / modulo esiste e None
se no. Aggiorna la tua risposta per Python 2, poiché mascherare ImportError mi ha fatto impazzire ieri xP
Dopo aver usato la risposta di Yarbelk, l'ho fatto per non dover importare ìmp
.
try:
__import__('imp').find_module('eggs')
# Make things with supposed existing module
except ImportError:
pass
Utile in Django settings.py
per esempio.
Il softwareModuleNotFoundError
è stato introdotto in Python 3.6 e può essere utilizzato per questo scopo
try:
import eggs
except ModuleNotFoundError:
# Error handling
pass
L'errore viene generato quando non è possibile trovare un modulo o uno dei suoi genitori . Così
try:
import eggs.sub
except ModuleNotFoundError as err:
# Error handling
print(err)
stamperebbe un messaggio che assomiglia No module named 'eggs'
se eggs
non è possibile trovare il modulo; ma stamperebbe qualcosa come No module named 'eggs.sub'
se sub
non fosse possibile trovare solo il modulo ma il eggs
pacchetto potrebbe essere trovato.
Consultare la documentazione del sistema di importazione per ulteriori informazioni suModuleNotFoundError
Fino a quando la risposta corrente non viene aggiornata, ecco la strada per Python 2
import pkgutil
import importlib
if pkgutil.find_loader(mod) is not None:
return importlib.import_module(mod)
return None
Molte risposte sfruttano la cattura di un ImportError
. Il problema è che non possiamo sapere cosa genera ImportError
.
Se si importa il modulo esistente e nel modulo si verifica un ImportError
errore (ad es. Errore di battitura nella riga 1), il risultato sarà che il modulo non esiste. Ci vorrà una grande quantità di backtracking per capire che il modulo esiste e che ImportError
viene catturato e fa sì che le cose falliscano silenziosamente.
ImportError
: modifica se non ti è chiaro.
La risposta di go_as come una fodera
python -c "help('modules');" | grep module
Mi sono imbattuto in questa domanda durante la ricerca di un modo per verificare se un modulo è caricato dalla riga di comando e vorrei condividere i miei pensieri per quelli che mi seguono e cercano lo stesso:
Metodo del file di script Linux / UNIX : crea un file module_help.py
:
#!/usr/bin/env python
help('modules')
Quindi assicurati che sia eseguibile: chmod u+x module_help.py
E chiamalo con un pipe
a grep
:
./module_help.py | grep module_name
Richiama il built-in sistema di aiuto integrato . (Questa funzione è destinata all'uso interattivo .) Se non viene fornito alcun argomento, il sistema di aiuto interattivo si avvia sulla console dell'interprete. Se l'argomento è una stringa , la stringa viene cercata come nome di un argomento relativo a modulo , funzione, classe, metodo, parola chiave o documentazione e sulla console viene stampata una pagina di aiuto. Se l'argomento è qualsiasi altro tipo di oggetto, viene generata una pagina di aiuto sull'oggetto.
Metodo interattivo : nel caricamento della consolepython
>>> help('module_name')
Se si trova, chiudere la lettura digitando q
Per uscire dalla sessione interattiva di Python, premere Ctrl+D
Metodo del file di script di Windows compatibile anche con Linux / UNIX e , in generale , migliore :
#!/usr/bin/env python
import sys
help(sys.argv[1])
Chiamandolo dal comando come:
python module_help.py site
Uscita:
Aiuto sul sito del modulo:
NAME
site - Aggiunge percorsi di ricerca del modulo per pacchetti di terze parti a sys.path.
FILE
/usr/lib/python2.7/site.py
MODULE DOCS
http://docs.python.org/library/site
DESCRIPTION
...
:
e dovresti premere q
per uscire dalla modalità interattiva.
Usandolo modulo sconosciuto:
python module_help.py lkajshdflkahsodf
Uscita:
nessuna documentazione Python trovata per 'lkajshdflkahsodf'
ed esci.
Utilizzare una delle funzioni di pkgutil , ad esempio:
from pkgutil import iter_modules
def module_exists(module_name):
return module_name in (name for loader, name, ispkg in iter_modules())
Un'istruzione if più semplice di AskUbuntu: come posso verificare se un modulo è installato in Python?
import sys
print('eggs' in sys.modules)
Potresti semplicemente scrivere un piccolo script che provi a importare tutti i moduli e ti dica quali non funzionano e quali funzionano:
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))
Produzione:
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
...
Un avvertimento questo tenterà di importare tutto in modo da vedere cose come PyYAML failed with error code: No module named pyyaml
perché il nome di importazione effettivo è solo yaml. Quindi, se conosci le tue importazioni, questo dovrebbe fare al caso tuo.
Ho scritto questa funzione di supporto:
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
Puoi anche usare importlib
direttamente
import importlib
try:
importlib.import_module(module_name)
except ImportError:
# Handle error
Non è possibile verificare in modo affidabile se il "modulo punteggiato" è importabile senza importare il pacchetto padre. Detto questo, ci sono molte soluzioni al problema "come verificare se esiste il modulo Python".
La soluzione seguente risolve il problema che il modulo importato può generare ImportError anche se esiste. Vogliamo distinguere quella situazione da tale in cui il modulo non esiste.
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
in 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