Узнаём версию модуля: от простого к продвинутому
Основы работы с версиями модулей Python
Как получить версию модуля, не завися от атрибута __version__?
Наиболее надёжным способом является использование модуля importlib.metadata, доступного начиная с Python 3.8. Этот метод гарантированно возвращает версию, указанную в метаданных пакета, даже если сам модуль не определяет атрибут версии.
from importlib.metadata import version, PackageNotFoundError
try:
ver = version('requests')
print(ver)
except PackageNotFoundError:
print('Модуль не установлен')Python module attributes (атрибуты модуля в python)
2.28.1
Python module version (версия модуля python)
Возможные проблемы:
- Модуль не установлен — возникает исключение PackageNotFoundError. Обрабатывайте его конструкцией try/except.
- Название модуля может отличаться от имени пакета (например, PIL vs Pillow). Используйте имя пакета как оно указано в pip list.
Как получить версию, если модуль определяет атрибут __version__?
Многие популярные библиотеки (например, requests, numpy, flask) имеют атрибут __version__ или version в корневом модуле. Прямой доступ к нему — самый простой способ.
import requests
print(requests.__version__)
Python cpp module (взаимодействие python с модулями c++)
2.28.1
Python module cv2 (модуль cv2 (opencv) в python)
Если атрибут отсутствует, можно проверить альтернативные названия через getattr:
import import_module
mod = import_module('some_module')
ver = getattr(mod, '__version__', getattr(mod, 'version', 'неизвестно'))
print(ver)Python encodings module (модуль encodings в python)
Проблемы:
- Не все модули реализуют этот атрибут.
- Название может быть в нижнем или верхнем регистре (VERSION). В таком случае перебор всех вариантов.
- Для встроенных модулей (os, sys) атрибут версии отсутствует.
Как узнать версию модуля в старых версиях Python (до 3.8)?
Используется модуль pkg_resources из пакета setuptools. Он медленнее и считается устаревшим, но всё ещё работает.
import pkg_resources
try:
ver = pkg_resources.get_distribution('requests').version
print(ver)
except pkg_resources.DistributionNotFound:
print('Модуль не установлен')Platform module python (модуль platform в python)
2.28.1
Python string module (модуль string в python)
Проблемы:
- Зависимость от setuptools (почти всегда есть, но не гарантируется).
- Функция get_distribution сканирует все установленные пакеты, что замедляет работу.
- В Python 3.12+ модуль может быть удалён.
Как получить версию модуля с помощью командной строки pip?
Команда pip show выводит метаданные пакета, включая версию. Можно выполнить её из Python через подпроцесс.
import subprocess, sys
def get_version_pip(package_name):
result = subprocess.run([sys.executable, '-m', 'pip', 'show', package_name],
capture_output=True, text=True)
if result.returncode != 0:
return None
for line in result.stdout.splitlines():
if line.startswith('Version:'):
return line.split(':')[1].strip()
return None
print(get_version_pip('requests'))Module sys python (модуль sys в python)
2.28.1
Python tkinter module (модуль tkinter в python)
Проблемы:
- Запуск внешнего процесса — медленно и менее безопасно.
- Зависимость от наличия pip в окружении.
- Вывод может быть локализован, строку 'Version:' нужно искать на английском.
Как проверить версию модуля через pip list с JSON?
Команда pip list --format=json возвращает структурированный список всех пакетов. Подходит для массовой проверки.
import subprocess, json, sys
def get_versions_from_pip_list():
result = subprocess.run([sys.executable, '-m', 'pip', 'list', '--format=json'],
capture_output=True, text=True)
packages = json.loads(result.stdout)
return {pkg['name']: pkg['version'] for pkg in packages}
versions = get_versions_from_pip_list()
print(versions.get('requests', 'не найден'))Python types module (модуль types в python)
2.28.1
Проблемы:
- Аналогичные подпроцессу: производительность, безопасность, локализация (JSON всегда на английском).
- Избыточность, если нужно проверить один модуль.
Расширенные примеры работы с версиями модулей
Проверка наличия модуля и получение его версии
from importlib.metadata import version, PackageNotFoundError
def safe_version(package_name):
try:
return version(package_name)
except PackageNotFoundError:
return None
except Exception as e:
return f'Ошибка: {e}'
for pkg in ['requests', 'numpy', 'nonexistent']:
v = safe_version(pkg)
print(f'{pkg}: {v}')requests: 2.28.1 numpy: 1.24.3 nonexistent: None
Получение версии нескольких модулей из списка требований
requirements = ['flask', 'django', 'pandas']
versions = {}
for req in requirements:
try:
versions[req] = version(req)
except PackageNotFoundError:
versions[req] = 'не установлен'
for pkg, ver in versions.items():
print(f'{pkg} == {ver}')flask == 2.3.3 django == 4.2.5 pandas == 2.0.3
Сравнение версий с использованием packaging
from importlib.metadata import version
from packaging.version import Version
required = '2.20.0'
installed = version('requests')
if Version(installed) >= Version(required):
print(f'Версия {installed} удовлетворяет требованию {required}')
else:
print(f'Требуется обновление: {installed} < {required}')Версия 2.28.1 удовлетворяет требованию 2.20.0
Получение версии с помощью importlib_metadata (Python < 3.8)
# Установите пакет: pip install importlib_metadata
from importlib_metadata import version, PackageNotFoundError
ver = version('requests')
print(ver)2.28.1
Динамическое получение версии через sys.modules
import sys
def get_version_from_module(mod_name):
if mod_name in sys.modules:
mod = sys.modules[mod_name]
return getattr(mod, '__version__', None)
return None
import requests
print(get_version_from_module('requests'))2.28.1
Этот способ работает, только если модуль уже импортирован. Не подходит для модулей, которые не загружены в память.
Проверка версии модуля через metadata вручную (low-level)
import pathlib, configparser
def version_from_metadata(package_name):
# Поиск METADATA в site-packages
import importlib.metadata as im
try:
dist = im.distribution(package_name)
return dist.metadata['Version']
except im.PackageNotFoundError:
return None
print(version_from_metadata('requests'))2.28.1