11 ответов:
вместо python2
чтобы проверить, если импорт может найти что-то в python2, используя
impimport imp try: imp.find_module('eggs') found = True except ImportError: found = Falseчтобы найти точечный импорт, вам нужно сделать больше:
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вы также можете использовать
pkgutil.find_loader(более или менее то же самое, что и часть python3import pkgutil eggs_loader = pkgutil.find_loader('eggs') found = eggs_loader is not NonePython3
Python3 ≤ 3.3
вы должны использовать
importlib, как я пошел об этом, было:import importlib spam_loader = importlib.find_loader('spam') found = spam_loader is not Noneмое ожидание, если вы можете найти загрузчик для него-то оно и существует. Вы также можете быть немного умнее, например, отфильтровывать, какие загрузчики вы примете. Например:
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)Python3 ≥ 3.4
В Питон3.4
importlib.find_loaderpython docs был осужден в пользуimportlib.util.find_spec. Рекомендуемый метод -importlib.util.find_spec. Есть и другие, какimportlib.machinery.FileFinder, что полезно, если вы после определенного файла для загрузки. Выяснение того, как их использовать, выходит за рамки этот.import importlib spam_spec = importlib.util.find_spec("spam") found = spam_spec is not Noneэто также работает с относительным импортом, но вы должны поставить начало пакет, так что вы могли бы сделать:
import importlib spam_spec = importlib.util.find_spec("..spam", package="eggs.bar") found = spam_spec is not None spam_spec.name == "eggs.spam"хотя я уверен, что существует причина для этого - я не уверен, что это будет.
предупреждение
при попытке найти подмодуль, он будет импортировать Родительский модуль (для все из вышеперечисленных методов)!
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')комментарии приветствуются о это
благодарности
- @rvighne для importlib
- @lucas-guido для python3. 3 + depricating
find_loader- @enpenax для pkgutils.поведение find_loader в python2. 7
после использования ответа ярбелька, я сделал это для не нужно импортировать
ìmp.try: __import__('imp').find_module('eggs') # Make things with supposed existing module except ImportError: passполезно в например.
Python 2, не полагаясь на ImportError
пока текущий ответ не будет обновлен, вот путь для Python 2
import pkgutil import importlib if pkgutil.find_loader(mod) is not None: return importlib.import_module(mod) return Noneпочему другой ответ?
многие ответы используют ловлю
ImportError. Проблема в том, что мы не можем знать, что бросаетImportError.если вы импортируете existant модуль и там оказывается
ImportErrorв вашем модуле (например, опечатка в строке 1), результат будет пусть ваш модуль не существует. Это займет у вас довольно много времени, чтобы выяснить, что ваш модуль существует иImportErrorпойман и делает вещи терпят неудачу молча.
использовать функции pkgutil, например:
from pkgutil import iter_modules def module_exists(module_name): return module_name in (name for loader, name, ispkg in iter_modules())
я столкнулся с этим вопросом при поиске способа проверить, загружен ли модуль из командная строка и хотел бы поделиться своими мыслями для тех, кто идет за мной и ищет то же самое:
Linux/UNIX script file method: файл
module_help.py:#!/usr/bin/env python help('modules')затем убедитесь, что это исполняемый файл:
chmod u+x module_help.pyи назвать его с
pipeдоgrep:./module_help.py | grep module_nameвызвать система поможет. (Эта функция предназначен для интерактивного использования.) Если аргумент не задан, интерактивная справочная система запускается на консоли интерпретатора. Если аргумент строка, затем строка ищется как имя a модуль, функция, класс, метод, ключевое слово или раздел документации, и страница справки печатается на консоли. Если аргументом является любой другой вид объекта, то на странице справки объект создается.
интерактивный метод: в консоли нагрузка
python>>> help('module_name')если найдено, прекратите чтение, набрав
q
Для выхода из интерактивного сеанса python нажмите Ctrl + Dметод файла сценария Windows также совместим с Linux / UNIX,и лучше в целом:
#!/usr/bin/env python import sys help(sys.argv[1])вызов его из команды, как:
python module_help.py siteвыводит:
справка на сайте модуль:
NAMEсайт-добавление путей поиска модуля для сторонних пакетов в sys.путь.
FILE/usr/lib/python2.7/site.py
MODULE DOCShttp://docs.python.org/library/site
DESCRIPTION
...
:и вам придется нажать
qдля выхода интерактивный режим.используя его неизвестный модуль:
python module_help.py lkajshdflkahsodfвыводит:
не найдено документации на Python для 'lkajshdflkahsodf'
и выход.
вы можете просто написать небольшой скрипт, который будет пытаться импортировать все модули и сказать вам, какие из них не работают и какие из них работают:
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))выход:
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 ...слово предупреждения это будет пытаться импортировать все так что вы увидите вещи, как
PyYAML failed with error code: No module named pyyamlпотому что фактическое имя импорта - это просто yaml. Так что пока вы знаете свой импорт, это должно сделать трюк для вас.
вы также можете использовать
importlibнапрямуюimport importlib try: importlib.import_module(module_name) except ImportError: # Handle error
Python 3 > = 3.6: ModuleNotFoundError
The
ModuleNotFoundErrorбыл введен в python 3.6 и может быть использован для этой целиtry: import eggs except ModuleNotFoundError: # Error handling passошибка возникает при модуль или один из его родителей не может быть найден. Так что
try: import eggs.sub except ModuleNotFoundError as err: # Error handling print(err)будет печатать сообщение, которое выглядит как
No module named 'eggs'Еслиeggsмодуль не может быть найден; но напечатать что-то вродеNo module named 'eggs.sub'если толькоsubмодуль не мог аeggsпакет может быть найден.посмотреть Документация системы импорта подробнее о
ModuleNotFoundError
Python 2:
нет способа надежно проверить, можно ли импортировать "точечный модуль" без импорта его родительского пакета. Говоря это, есть много решений проблемы "как проверить, существует ли модуль Python".
ниже Решение проблемы, что импортированный модуль может вызвать ImportError даже он существует. Мы хотим отличить ту ситуацию от такой, в которой модуль не существует.
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
в Django.utils.загрузка модуля.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
Comments