Получение перечня модулей Python: практическое руководство
Список модулей Python: базовые и альтернативные подходы
Термин 'список модулей Python' может означать разные наборы: встроенные модули интерпретатора, модули стандартной библиотеки, установленные дистрибутивы, модули в конкретной папке или уже загруженные в текущем процессе. Выбор способа зависит от цели: аудит окружения, диагностика импорта, построение документации или проверка зависимостей.
Основной подход для большинства задач состоит в комбинации нескольких источников. Для загруженных модулей используется sys.modules, для встроенных - sys.builtin_module_names, для установленных пакетов - importlib.metadata, для поиска по путям - pkgutil.iter_modules.
Пример получения списка уже импортированных модулей:
import sys
mods = sorted(sys.modules)
print(f'Загружено модулей: {len(mods)}')
print(mods[:15])Python module attributes (атрибуты модуля в python)
Загружено модулей: 42 ['__main__', '_abc', '_ast', '_codecs', '_collections', ...]
Python module version (версия модуля python)
Пояснение: словарь sys.modules содержит модули, которые уже были импортированы. Он не показывает модули, доступные для импорта, но еще не загруженные.
Пример вывода встроенных модулей:
import sys
for name in sys.builtin_module_names:
print(name)
Python module cv2 (модуль cv2 (opencv) в python)
_abc _ast _codecs ...
Python tkinter module (модуль tkinter в python)
Для установленных дистрибутивов применяется importlib.metadata:
from importlib.metadata import distributions
packages = sorted({dist.metadata['Name'] for dist in distributions()})
print(f'Установлено дистрибутивов: {len(packages)}')
print(packages[:10])Python types module (модуль types в python)
Установлено дистрибутивов: 25 ['attrs', 'certifi', 'charset-normalizer', 'idna', 'pip', ...]
Python module windows (модуль windows для python)
Этот способ показывает имена дистрибутивов, которые могут отличаться от имен импортируемых модулей. Например, дистрибутив Pillow обычно импортируется как PIL.
Как получить список модулей стандартной библиотеки через help('modules')?
Встроенная справочная система Python содержит команду modules. Она выводит большой перечень модулей, доступных для импорта в текущем окружении.
help('modules')Python module list (список модулей python)
Please wait a moment while I gather a list of all available modules... __future__ _abc _ast ...
Module functions python (функции модуля в python)
Вариант подходит для быстрого обзора, но вывод неудобен для программной обработки. Кроме того, в некоторых окружениях команда может выполняться заметное время.
Как получить перечень установленных пакетов через pip list?
Команда pip list показывает дистрибутивы, установленные в текущем окружении. Это удобно для аудита зависимостей и переноса окружения.
pip list
Package Version ---------- ------- pip 24.0 setuptools 69.0.0 ...
Формат --format=json дает машинно-читаемый результат:
pip list --format=json
[{'name': 'pip', 'version': '24.0'}, {'name': 'setuptools', 'version': '69.0.0'}]
Важно: pip list работает с дистрибутивами, а не с именами модулей. Для одного дистрибутива может быть несколько импортируемых пакетов.
Как найти модули в конкретной папке через pkgutil.iter_modules?
Модуль pkgutil предоставляет функцию iter_modules, которая перебирает модули в указанных путях.
import pkgutil
for module in pkgutil.iter_modules(['.']):
print(module.name, module.ispkg)
my_module False my_package True
Параметр path может содержать список каталогов. Если параметр не указан, перебираются пути из sys.path.
import pkgutil
modules = [m.name for m in pkgutil.iter_modules()]
print(len(modules))
print(sorted(modules)[:20])
150 ['__future__', '_aix_support', '_bootsubprocess', ...]
Метод не импортирует модули и не выполняет их код. Это безопасный способ обзора файловой структуры.
Как рекурсивно обойти пакеты через pkgutil.walk_packages?
Функция walk_packages выполняет рекурсивный обход пакетов и вложенных модулей.
import pkgutil
for module in pkgutil.walk_packages():
print(module.name)
abc aifc ... email email.charset email.encoders ...
Рекурсивный обход может быть медленным и иногда вызывает импорт пакетов для получения их путей. Для больших окружений применяется ограничение по глубине или фильтрация по префиксу.
Как получить список модулей через importlib.util.find_spec?
Функция find_spec позволяет проверить, доступен ли модуль для импорта, без его загрузки.
import importlib.util
names = ['sys', 'os', 'numpy', 'unknown_module']
for name in names:
spec = importlib.util.find_spec(name)
print(name, spec is not None)
sys True os True numpy True unknown_module False
Этот способ удобен для предварительной проверки зависимостей. Если модуль отсутствует, find_spec возвращает None.
Как получить модули, входящие в конкретный пакет?
Для обзора содержимого пакета используются атрибуты __all__, функция dir() и обход через pkgutil.
import json
print(hasattr(json, '__all__'))
print(dir(json)[:15])
False ['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', ...]
Атрибут __all__ определяет имена, которые экспортируются при from package import *. Он не всегда присутствует.
import pkgutil
import email
for m in pkgutil.iter_modules(email.__path__, email.__name__ + '.'):
print(m.name)
email.charset email.encoders email.errors ...
Как получить список загруженных модулей после запуска программы?
Сравнение sys.modules до и после импорта позволяет увидеть, какие модули были загружены.
import sys
before = set(sys.modules)
import xml.etree.ElementTree
after = set(sys.modules)
print(sorted(after - before))
['xml', 'xml.etree', 'xml.etree.ElementTree', ...]
Такой прием помогает анализировать скрытые зависимости и порядок загрузки.
Типичные проблемы и ошибки
sys.modulesпоказывает только уже импортированные модули. Для полного списка доступных модулей требуется другой инструмент.help('modules')может работать медленно и выводит текст, который сложно разбирать автоматически.pkgutil.iter_modules()не импортирует модули, но может не видеть namespace-пакеты без файла__init__.py.pip listотображает дистрибутивы, а не имена импортируемых модулей. Соответствие не всегда очевидно.importlib.metadataнаходит только дистрибутивы с метаданными. Модули, добавленные вручную вsys.path, могут отсутствовать.- Ошибка
ModuleNotFoundErrorвозникает, когда модуль отсутствует вsys.pathили не установлен. - В виртуальном окружении список модулей отличается от глобального Python. Команды требуется запускать в нужном окружении.
- Некоторые модули доступны только на определенных платформах. Например,
winregприсутствует в Windows, но отсутствует в Linux.
Расширенные примеры получения и обработки списков модулей Python
Ниже приведены примеры, которые показывают не только вывод списка, но и фильтрацию, экспорт, анализ зависимостей и проверку доступности модулей.
Как собрать доступные модули из sys.path?
import pkgutil
modules = []
for module in pkgutil.iter_modules():
modules.append(module.name)
print(f'Доступно модулей: {len(modules)}')
print(sorted(modules)[:10])
Доступно модулей: 152 ['__future__', '_aix_support', '_bootsubprocess', '_collections_abc', ...]
Пояснение: перебираются пути из sys.path. В список попадают модули и пакеты, которые могут быть импортированы.
Как выполнить фильтрацию модулей по префиксу?
import pkgutil
prefix = 'json'
found = [m.name for m in pkgutil.iter_modules() if m.name.startswith(prefix)]
print(found)
['json']
Пояснение: фильтрация по префиксу помогает найти модули, связанные с определенной темой или библиотекой.
Как получить версии установленных дистрибутивов?
from importlib.metadata import distributions
for dist in sorted(distributions(), key=lambda d: d.metadata['Name'].lower()):
line = dist.metadata['Name'] + '==' + dist.version
print(line)
attrs==23.1.0 certifi==2024.2.2 ...
Пояснение: importlib.metadata возвращает объекты дистрибутивов. Их можно сортировать и выводить в формате requirements.
Как экспортировать список модулей в JSON?
import json
import pkgutil
items = []
for m in pkgutil.iter_modules():
items.append({'name': m.name, 'is_package': m.ispkg})
with open('modules.json', 'w', encoding='utf-8') as f:
json.dump(items, f, ensure_ascii=False, indent=2)
print('Сохранено', len(items), 'записей')
Сохранено 152 записей
Пояснение: результат можно использовать для отчетов, сравнения окружений или документации.
Как проверить доступность модуля без импорта?
import importlib.util
def module_available(name):
return importlib.util.find_spec(name) is not None
for name in ['sys', 'os', 'pandas', 'unknown']:
print(name, module_available(name))
sys True os True pandas False unknown False
Пояснение: функция find_spec не выполняет код модуля, поэтому проверка безопасна.
Как проанализировать зависимости дистрибутива?
from importlib.metadata import requires
deps = requires('requests')
for dep in deps:
print(dep)
charset-normalizer (>=3.2.0,<4) idna (>=2.5,<4) urllib3 (>=1.21.1,<3) certifi (>=2017.4.17)
Пояснение: requires возвращает список требований дистрибутива. Это помогает понять зависимости пакета.
Как сравнить sys.modules до и после импорта?
import sys
before = set(sys.modules)
import csv
import sqlite3
after = set(sys.modules)
new_modules = sorted(after - before)
print(new_modules)
['_sqlite3', 'csv', 'sqlite3']
Пояснение: сравнение множеств показывает модули, которые были загружены в результате импорта.
Как выполнить рекурсивный обход пакета с ограничением глубины?
import pkgutil
def walk_package(package_name, max_depth=1):
package = __import__(package_name)
prefix = package_name + '.'
for m in pkgutil.walk_packages(package.__path__, prefix):
depth = m.name.count('.') - package_name.count('.')
if depth <= max_depth:
print(m.name)
walk_package('email', max_depth=1)
email.charset email.encoders email.errors email.feedparser ...
Пояснение: ограничение глубины уменьшает время обхода и объем вывода.
Как найти дубликаты модулей в sys.path?
import sys
from collections import defaultdict
paths = defaultdict(list)
for p in sys.path:
paths[p].append(p)
duplicates = {k: v for k, v in paths.items() if len(v) > 1}
print(duplicates)
{}
Пояснение: дубликаты путей могут приводить к загрузке разных версий модулей. Пример показывает базовую проверку.
Как получить список модулей из виртуального окружения?
import sys
import subprocess
result = subprocess.run(
[sys.executable, '-m', 'pip', 'list', '--format=json'],
capture_output=True,
text=True
)
print(result.stdout[:200])
[{'name': 'pip', 'version': '24.0'}, ...]
Пояснение: вызов pip через sys.executable гарантирует использование интерпретатора текущего окружения.
Как проанализировать импорты скрипта через modulefinder?
from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script('example.py')
print(len(finder.modules))
for name in list(finder.modules)[:10]:
print(name)
25 __main__ os sys ...
Пояснение: modulefinder анализирует импорты в скрипте и строит список модулей, которые могут быть загружены.
Как найти модули в zip-архиве?
import pkgutil
import zipfile
with zipfile.ZipFile('my_modules.zip') as zf:
for m in pkgutil.iter_modules(zf.namelist()):
print(m.name)
module_a module_b package_c
Пояснение: pkgutil.iter_modules может работать с zip-архивами, если они добавлены в sys.path или передан список имен.
Как выполнить динамический импорт модулей из списка?
import importlib
names = ['math', 'json', 'datetime']
for name in names:
module = importlib.import_module(name)
print(name, module.__file__ if hasattr(module, '__file__') else 'built-in')
math built-in json /usr/lib/python3.11/json/__init__.py datetime /usr/lib/python3.11/datetime.py
Пояснение: importlib.import_module загружает модуль по имени. Это полезно для плагинов и динамических систем.
Как получить информацию о модуле через spec?
import importlib.util
spec = importlib.util.find_spec('json')
print(spec.name)
print(spec.origin)
print(spec.submodule_search_locations)
json /usr/lib/python3.11/json/__init__.py _NamespacePath(['/usr/lib/python3.11/json'])
Пояснение: объект spec содержит путь к файлу, имя и другие сведения, которые помогают в диагностике импорта.
Как вывести только пакеты из общего списка?
import pkgutil
packages = [m.name for m in pkgutil.iter_modules() if m.ispkg]
print(len(packages))
print(sorted(packages)[:10])
45 ['asyncio', 'collections', 'concurrent', 'ctypes', 'dbm', ...]
Пояснение: флаг ispkg позволяет отделить пакеты от одиночных модулей.
Как обнаружить namespace-пакеты?
import pkgutil
for m in pkgutil.iter_modules():
if m.ispkg:
print(m.name)
asyncio collections ...
Пояснение: namespace-пакеты не всегда имеют файл __init__.py. Для их обнаружения иногда требуются дополнительные инструменты, например importlib.resources.
Как проверить конфликты имен модулей?
import sys
import os
name = 'json'
paths = []
for p in sys.path:
candidate = p + '/' + name + '.py'
if os.path.exists(candidate):
paths.append(candidate)
print(paths)
['/usr/lib/python3.11/json.py']
Пояснение: если один и тот же модуль найден в нескольких каталогах, загружается первый по порядку в sys.path. Это может приводить к неожиданному поведению.