用于列出Jupyter笔记本中使用的软件包版本的软件包

msx*_*msx 11 python python-3.x

我似乎记得有一个软件包打印了Jupyter笔记本中使用的Python软件包的版本和相关信息,因此其中的结果是可重现的.但我不记得包的名称.你们有人能指出我正确的方向吗?

提前致谢!

Tim*_*sev 13

单线:

# In[1]:
import pandas as pd
import numpy as np
import tensorflow as tf

print('\n'.join(f'{m.__name__}=={m.__version__}' for m in globals().values() if getattr(m, '__version__', None)))
Run Code Online (Sandbox Code Playgroud)

输出:

pandas==1.1.1
numpy==1.19.1
tensorflow==2.2.0
Run Code Online (Sandbox Code Playgroud)

  • 在打印函数中添加==,使其与需求格式类似 (2认同)

Viv*_*san 11

这将获得所有已安装的软件包

import pip #needed to use the pip functions
for i in pip.get_installed_distributions(local_only=True):
    print(i)
Run Code Online (Sandbox Code Playgroud)

从当前笔记本中获取软件包列表

import types
def imports():
    for name, val in globals().items():
        if isinstance(val, types.ModuleType):
            yield val.__name__
list(imports())
Run Code Online (Sandbox Code Playgroud)

  • 运行第一个代码块时出现错误: `AttributeError: module 'pip' has no attribute 'get_installed_distributions'` `pip.__version__ == '19.2.3'` (3认同)
  • 感谢您的回复,但我正在寻找一个仅列出相关笔记本中使用的软件包的软件包。 (2认同)

Ale*_*ler 9

我通过结合已经提供的两种解决方案拼凑了这个答案.我最终想生成一个requirements.txt类型的文件,以便与令人敬畏的Binder网站一起使用.显然,我不想要pip freeze我的整个系统,但我也不想为每个笔记本创建单独的虚拟环境(最终我的问题源于此).

这将输出格式良好的requirements.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's 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))
Run Code Online (Sandbox Code Playgroud)

样本输出:

scipy==0.19.0
requests==2.18.1
Pillow==5.0.0
numpy==1.13.0
matplotlib==2.0.2
Run Code Online (Sandbox Code Playgroud)

编辑2018-04-21:pip版本10停止支持该.get_installed_distributions()方法.pkg_resources.working_set改为使用.

  • 这个答案很好,因为它决定了包的版本,即使你只导入了一个子包(例如,如果你导入了 `scipy.integrate`,则是 `scipy` 的版本)。谢谢! (2认同)

小智 5

我对@Alex P. Miller 的回答进行了一些改进(抱歉,我没有足够的代表直接对他的回答进行“评论”)

  1. 在区分大小写导致问题的地方自动使用模块名称
  2. 还将没有版本号的模块列为“未知”,以明确无法找到匹配项。
  3. 如果可以检测到它,还会列出内置模块。
# show versions of packages
# adopted from /sf/ask/2830025201/

    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's 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))
Run Code Online (Sandbox Code Playgroud)