Пакет для листинга версий пакетов, используемых в ноутбуке Jupyter
Кажется, я помню, что есть пакет, в котором были напечатаны версии и соответствующая информация о пакетах Python, используемых в ноутбуке Jupyter, поэтому результаты в нем были воспроизводимыми. Но я не могу вспомнить имя пакета. Может ли кто-нибудь из вас указать мне в правильном направлении?
Спасибо заранее!
Ответы
Ответ 1
Получает все установленные пакеты
import pip #needed to use the pip functions
for i in pip.get_installed_distributions(local_only=True):
print(i)
Получить список пакетов из текущего ноутбука
import types
def imports():
for name, val in globals().items():
if isinstance(val, types.ModuleType):
yield val.__name__
list(imports())
Ответ 2
Я обдумал этот ответ, объединив два уже предоставленных решения. В конечном итоге я хотел создать файл типа require.txt, чтобы его можно было легко использовать на замечательном веб-сайте Binder. Очевидно, что я не хочу pip freeze
всю систему целиком, но я также не хочу создавать отдельные виртуальные среды для каждого ноутбука (отсюда и моя проблема).
Это выводит красиво отформатированную строку типа require.txt и обрабатывает некоторые сложности, возникающие при использовании import from
а не только import
.
Получить локально импортированные модули из текущей записной книжки
import pkg_resources
import types
def get_imports():
for name, val in globals().items():
if isinstance(val, types.ModuleType):
# Split ensures you get root package,
# not just imported function
name = val.__name__.split(".")[0]
elif isinstance(val, type):
name = val.__module__.split(".")[0]
# Some packages are weird and have different
# imported names vs. system/pip names. Unfortunately,
# there is no systematic way to get pip names from
# a package imported name. You'll have to had
# exceptions to this list manually!
poorly_named_packages = {
"PIL": "Pillow",
"sklearn": "scikit-learn"
}
if name in poorly_named_packages.keys():
name = poorly_named_packages[name]
yield name
imports = list(set(get_imports()))
# The only way I found to get the version of the root package
# from only the name of the package is to cross-check the names
# of installed packages vs. imported packages
requirements = []
for m in pkg_resources.working_set:
if m.project_name in imports and m.project_name!="pip":
requirements.append((m.project_name, m.version))
for r in requirements:
print("{}=={}".format(*r))
Пример вывода:
scipy==0.19.0
requests==2.18.1
Pillow==5.0.0
numpy==1.13.0
matplotlib==2.0.2
РЕДАКТИРОВАНИЕ 2018-04-21: версия 10 .get_installed_distributions()
перестала поддерживать метод .get_installed_distributions()
. pkg_resources.working_set
этого используйте pkg_resources.working_set
.
Ответ 3
Я сделал некоторые улучшения в ответе @Alex P. Miller, чтобы (извините, у меня недостаточно повторений, чтобы "прокомментировать" его ответ)
- Автоматически работает с именами модулей, где чувствительность к регистру вызывает проблемы
- Также перечисляет модули без номеров версий как "неизвестные", чтобы было ясно, что они не могут найти соответствие.
- также перечисляет встроенные модули, если он может обнаружить его.
# show versions of packages
# adopted from https://stackoverflow.com/questions/40428931/package-for-listing-version-of-packages-used-in-a-jupyter-notebook
def get_imports():
for name, val in globals().items():
if isinstance(val, types.ModuleType):
# Split ensures you get root package,
# not just imported function
name = val.__name__.split(".")[0]
elif isinstance(val, type):
name = val.__module__.split(".")[0]
# Some packages are weird and have different
# imported names vs. system/pip names. Unfortunately,
# there is no systematic way to get pip names from
# a package imported name. You'll have to add
# exceptions to this list manually!
poorly_named_packages = {
"sklearn": "scikit-learn"
}
if name in poorly_named_packages.keys():
name = poorly_named_packages[name]
yield name.lower()
imports = list(set(get_imports()))
# The only way I found to get the version of the root package
# from only the name of the package is to cross-check the names
# of installed packages vs. imported packages
modules = []
for m in sys.builtin_module_names:
if m.lower() in imports and m !='builtins':
modules.append((m,'Python BuiltIn'))
imports.remove(m.lower())
for m in pkg_resources.working_set:
if m.project_name.lower() in imports and m.project_name!="pip":
modules.append((m.project_name, m.version))
imports.remove(m.project_name.lower())
for m in sys.modules:
if m.lower() in imports and m !='builtins':
modules.append((m,'unknown'))
# print('System=='+platform.system()+' '+platform.release()+'; Version=='+platform.version())
for r in modules:
print("{}=={}".format(*r))
Ответ 4
Я думаю, что подходы, основанные на pip
, превосходят с точки зрения функциональности, но, возможно, ОП пытался вспомнить название расширения version_information
для Jupyter: https://pypi.org/project/version_information/
Ответ 5
Другое решение (на основе ответа Vaeka answer):
import types
def imports():
for name, val in globals().items():
if isinstance(val, types.ModuleType):
yield val.__name__
excludes = ['builtins', 'types', 'sys']
imported_modules = [module for module in imports() if module not in excludes]
clean_modules = []
for module in imported_modules:
sep = '.' # to handle 'matplotlib.pyplot' cases
rest = module.split(sep, 1)[0]
clean_modules.append(rest)
changed_imported_modules = list(set(clean_modules)) # drop duplicates
pip_modules = !pip freeze # you could also use '!conda list' with anaconda
for module in pip_modules:
name, version = module.split('==')
if name in changed_imported_modules:
print(name + '\t' + version)
Пример вывода:
astropy 3.2.1
matplotlib 3.1.0
numpy 1.16.4
pandas 0.25.0