如何获得本地安装的Python模块列表?

我想获得Python模块的列表,这些模块位于我的Python安装(UNIX服务器)中。

如何在计算机中安装Python模块列表?


1
help('modules')

在Python shell/提示符中。


解决方案

我的50美分从Python脚本获得一个类似于pip freeze的列表:

1
2
3
4
5
import pip
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages])
print(installed_packages_list)

作为(太长的)一行:

1
sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])

给:

1
2
3
4
5
['behave==1.2.4', 'enum34==1.0', 'flask==0.10.1', 'itsdangerous==0.24',
 'jinja2==2.7.2', 'jsonschema==2.3.0', 'markupsafe==0.23', 'nose==1.3.3',
 'parse-type==0.3.4', 'parse==1.6.4', 'prettytable==0.7.2', 'requests==2.3.0',
 'six==1.6.1', 'vioozer-metadata==0.1', 'vioozer-users-server==0.1',
 'werkzeug==0.9.4']

范围

此解决方案适用于系统范围或虚拟环境范围,并覆盖由setuptoolspip和(上帝禁止)easy_install安装的包。

我的用例

我将此调用的结果添加到烧瓶服务器,因此当我使用http://example.com/exampleServer/environment调用它时,我将得到安装在服务器的virtualenv上的包列表。它使调试变得容易得多。

警告

我注意到这种技术的一个奇怪行为——当Python解释器与setup.py文件在同一个目录中调用时,它不会列出setup.py安装的包。

步骤复制:

创建虚拟环境

1
2
3
4
5
6
$ cd /tmp
$ virtualenv test_env
New python executable in test_env/bin/python
Installing setuptools, pip...done.
$ source test_env/bin/activate
(test_env) $

setup.py克隆一个git repo

1
2
3
4
5
6
7
(test_env) $ git clone https://github.com/behave/behave.git
Cloning into 'behave'...
remote: Reusing existing pack: 4350, done.
remote: Total 4350 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (4350/4350), 1.85 MiB | 418.00 KiB/s, done.
Resolving deltas: 100% (2388/2388), done.
Checking connectivity... done.

我们在/tmp/behave中有behave's setup.py:

1
2
(test_env) $ ls /tmp/behave/setup.py
/tmp/behave/setup.py

从git repo安装python包

1
2
3
4
5
(test_env) $ cd /tmp/behave && python setup.py install
running install
...
Installed /private/tmp/test_env/lib/python2.7/site-packages/enum34-1.0-py2.7.egg
Finished processing dependencies for behave==1.2.5a1

如果我们从/tmp运行上述解决方案

1
2
3
4
5
6
>>> import pip
>>> sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])
['behave==1.2.5a1', 'enum34==1.0', 'parse-type==0.3.4', 'parse==1.6.4', 'six==1.6.1']
>>> import os
>>> os.getcwd()
'/private/tmp'

如果我们从/tmp/behave运行上述解决方案

1
2
3
4
5
6
>>> import pip
>>> sorted(["%s==%s" % (i.key, i.version) for i in pip.get_installed_distributions()])
['enum34==1.0', 'parse-type==0.3.4', 'parse==1.6.4', 'six==1.6.1']
>>> import os
>>> os.getcwd()
'/private/tmp/behave'

第二个示例中缺少behave==1.2.5a1,因为工作目录包含behavesetup.py文件。

我在文件中找不到有关这个问题的任何参考资料。也许我应该为它打开一个漏洞。


现在,我自己尝试了这些方法,并且得到了宣传的结果:所有模块。

唉,实际上您并不太关心stdlib,您知道python安装会得到什么。

真的,我想要我安装的东西。

令人惊讶的是,实际上效果还不错的是:

1
pip freeze

返回:

1
2
3
4
5
6
7
8
9
Fabric==0.9.3
apache-libcloud==0.4.0
bzr==2.3b4
distribute==0.6.14
docutils==0.7
greenlet==0.3.1
ipython==0.10.1
iterpipes==0.4
libxml2-python==2.6.21

我之所以说"令人惊讶",是因为软件包安装工具正是人们期望找到该功能的确切位置,尽管不是在"冻结"的名称下,而是python打包是如此奇怪,以至于我对这个工具的意义感到惊讶。Pip 0.8.2, Python 2.7。


ipython中,您可以键入"import选项卡"。

在标准Python解释器中,您可以键入"help('modules')"。

在命令行中,可以使用pydoc modules

在脚本中,调用pkgutil.iter_modules()


自pip 1.3版本以来,您可以访问:

1
pip list

这似乎是"pip freeze"的语法糖。它将列出所有特定于您的安装或virtualenv的模块,以及它们的版本号。不幸的是,它不显示任何模块的当前版本号,也不洗碗或擦鞋。


我只是用这个来查看当前使用的模块:

1
2
import sys as s
s.modules.keys()

它显示了运行在python上的所有模块。

所有内置模块使用:

1
s.modules

它是一个包含所有模块和导入对象的dict。


在正常的外壳中使用即可

1
pydoc modules


从pip 10开始,接受的答案将不再有效。开发团队已经删除了对get_installed_distributions例程的访问。在setuptools中有一个替代函数用于执行相同的操作。下面是一个与pip 10一起工作的替代版本:

1
2
3
4
5
import pkg_resources
installed_packages = pkg_resources.working_set
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages])
print(installed_packages_list)

请让我知道,如果它将或不工作,在以前版本的pip,太。


如果需要列出Python shell中已安装的包,可以使用help命令,如下所示

1
>>help('modules package')


我通常使用pip list获取包列表(带有版本)。

当然,这也适用于虚拟环境。


使用pkgutil.iter_modules进行非常简单的搜索

1
2
3
4
5
6
from pkgutil import iter_modules
a=iter_modules()
while True:
    try: x=a.next()
    except: break
    if 'searchstr' in x[1]: print x[1]

我在OS x上遇到了一个自定义安装的python 2.7,它要求X11列出已安装的模块(使用help和pydoc)。

为了能够列出所有模块而不安装X11,我运行pydoc作为http-server,即:

1
pydoc -p 12345

然后可以将Safari直接指向http://localhost:12345/查看所有模块。


在windows上,在cmd中输入这个

1
c:\python\libs>python -m pip freeze


除了使用pip freeze,我还在我的虚拟环境中安装了蛋黄。


要获得所有可用的模块,运行sys.modules要获得所有已安装的模块(读取:由pip安装),可以查看pip.get_installed_distributions()

第二个目的,示例代码:

1
2
3
4
5
6
7
import pip
for package in pip.get_installed_distributions():
    name = package.project_name # SQLAlchemy, Django, Flask-OAuthlib
    key = package.key # sqlalchemy, django, flask-oauthlib
    module_name = package._get_metadata("top_level.txt") # sqlalchemy, django, flask_oauthlib
    location = package.location # virtualenv lib directory etc.
    version = package.version # version number


这个解决方案主要基于模块importlibpkgutil,可以使用CPython 3.4和CPython 3.5,但是不支持CPython 2。

解释

sys.builtin_module_names -命名所有内置模块(看我的答案)pkgutil.iter_modules() -返回所有可用模块的信息importlib.util.find_spec() -如果存在,返回一个关于导入模块的信息BuiltinImporter -内置模块(文档)导入器SourceFileLoader -标准Python模块的导入器(默认情况下扩展名为*.py)(文档)ExtensionFileLoader -模块作为共享库的导入器(在C或c++上编写)

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import sys
import os
import shutil
import pkgutil
import importlib
import collections

if sys.version_info.major == 2:
    raise NotImplementedError('CPython 2 is not supported yet')


def main():

    # name this file (module)
    this_module_name = os.path.basename(__file__).rsplit('.')[0]

    # dict for loaders with their modules
    loaders = collections.OrderedDict()

    # names`s of build-in modules
    for module_name in sys.builtin_module_names:

        # find an information about a module by name
        module = importlib.util.find_spec(module_name)

        # add a key about a loader in the dict, if not exists yet
        if module.loader not in loaders:
            loaders[module.loader] = []

        # add a name and a location about imported module in the dict
        loaders[module.loader].append((module.name, module.origin))

    # all available non-build-in modules
    for module_name in pkgutil.iter_modules():

        # ignore this module
        if this_module_name == module_name[1]:
            continue

        # find an information about a module by name
        module = importlib.util.find_spec(module_name[1])

        # add a key about a loader in the dict, if not exists yet
        loader = type(module.loader)
        if loader not in loaders:
            loaders[loader] = []

        # add a name and a location about imported module in the dict
        loaders[loader].append((module.name, module.origin))

    # pretty print
    line = '-' * shutil.get_terminal_size().columns
    for loader, modules in loaders.items():
        print('{0}
{1}: {2}
{0}'
.format(line, len(modules), loader))
        for module in modules:
            print('{0:30} | {1}'.format(module[0], module[1]))


if __name__ == '__main__':
    main()

使用

对于CPython3.5(截短)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
$ python3.5 python_modules_info.py
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
30: <class '_frozen_importlib.BuiltinImporter'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_ast                           | built-in
_codecs                        | built-in
_collections                   | built-in
_functools                     | built-in
_imp                           | None
_io                            | built-in
_locale                        | built-in
_operator                      | built-in
_signal                        | built-in
_sre                           | built-in
_stat                          | built-in
_string                        | built-in
_symtable                      | built-in
_thread                        | built-in
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
227: <class '_frozen_importlib_external.SourceFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__future__                     | /usr/local/lib/python3.5/__future__.py
_bootlocale                    | /usr/local/lib/python3.5/_bootlocale.py
_collections_abc               | /usr/local/lib/python3.5/_collections_abc.py
_compat_pickle                 | /usr/local/lib/python3.5/_compat_pickle.py
_compression                   | /usr/local/lib/python3.5/_compression.py
_dummy_thread                  | /usr/local/lib/python3.5/_dummy_thread.py
_markupbase                    | /usr/local/lib/python3.5/_markupbase.py
_osx_support                   | /usr/local/lib/python3.5/_osx_support.py
_pydecimal                     | /usr/local/lib/python3.5/_pydecimal.py
_pyio                          | /usr/local/lib/python3.5/_pyio.py
_sitebuiltins                  | /usr/local/lib/python3.5/_sitebuiltins.py
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
64: <class '_frozen_importlib_external.ExtensionFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_bisect                        | /usr/local/lib/python3.5/lib-dynload/_bisect.cpython-35m-x86_64-linux-gnu.so
_bz2                           | /usr/local/lib/python3.5/lib-dynload/_bz2.cpython-35m-x86_64-linux-gnu.so
_codecs_cn                     | /usr/local/lib/python3.5/lib-dynload/_codecs_cn.cpython-35m-x86_64-linux-gnu.so
_codecs_hk                     | /usr/local/lib/python3.5/lib-dynload/_codecs_hk.cpython-35m-x86_64-linux-gnu.so
_codecs_iso2022                | /usr/local/lib/python3.5/lib-dynload/_codecs_iso2022.cpython-35m-x86_64-linux-gnu.so
(****************************truncated*******************************)

对于CPython3.4(截短)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
$ python3.4 python_modules_info.py
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
54: <class '_frozen_importlib.BuiltinImporter'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_ast                           | built-in
_bisect                        | built-in
_codecs                        | built-in
_collections                   | built-in
_datetime                      | built-in
_elementtree                   | built-in
_functools                     | built-in
_heapq                         | built-in
_imp                           | None
_io                            | built-in
_locale                        | built-in
_md5                           | built-in
_operator                      | built-in
_pickle                        | built-in
_posixsubprocess               | built-in
_random                        | built-in
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
246: <class '_frozen_importlib.SourceFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
__future__                     | /usr/lib/python3.4/__future__.py
_bootlocale                    | /usr/lib/python3.4/_bootlocale.py
_collections_abc               | /usr/lib/python3.4/_collections_abc.py
_compat_pickle                 | /usr/lib/python3.4/_compat_pickle.py
_dummy_thread                  | /usr/lib/python3.4/_dummy_thread.py
_markupbase                    | /usr/lib/python3.4/_markupbase.py
_osx_support                   | /usr/lib/python3.4/_osx_support.py
_pyio                          | /usr/lib/python3.4/_pyio.py
(****************************truncated*******************************)
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
44: <class '_frozen_importlib.ExtensionFileLoader'>
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_bz2                           | /usr/lib/python3.4/lib-dynload/_bz2.cpython-34m-x86_64-linux-gnu.so
_codecs_cn                     | /usr/lib/python3.4/lib-dynload/_codecs_cn.cpython-34m-x86_64-linux-gnu.so
_codecs_hk                     | /usr/lib/python3.4/lib-dynload/_codecs_hk.cpython-34m-x86_64-linux-gnu.so
_codecs_iso2022                | /usr/lib/python3.4/lib-dynload/_codecs_iso2022.cpython-34m-x86_64-linux-gnu.so
_codecs_jp                     | /usr/lib/python3.4/lib-dynload/_codecs_jp.cpython-34m-x86_64-linux-gnu.so
_codecs_kr                     | /usr/lib/python3.4/lib-dynload/_codecs_kr.cpython-34m-x86_64-linux-gnu.so
_codecs_tw                     | /usr/lib/python3.4/lib-dynload/_codecs_tw.cpython-34m-x86_64-linux-gnu.so
_crypt                         | /usr/lib/python3.4/lib-dynload/_crypt.cpython-34m-x86_64-linux-gnu.so
(****************************truncated*******************************)


pip freeze完成所有查找包的任务,但是您可以简单地编写以下命令来列出python包所在的所有路径。

1
2
>>> import site; site.getsitepackages()
['/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages']

这是受亚当·马坦(Adam Matan)的回答启发(公认的答案):

1
2
3
4
5
6
7
8
9
10
11
import tabulate
try:
  from pip import get_installed_distributions
except:
  from pip._internal.utils.misc import get_installed_distributions

tabpackages = []
for _, package in sorted([('%s %s' % (i.location, i.key), i) for i in get_installed_distributions()]):
  tabpackages.append([package.location, package.key, package.version])

print(tabulate.tabulate(tabpackages))

然后打印出表格的形式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
19:33 pi@rpi-v3 [iot-wifi-2] ~/python$ python installed_packages.py
-------------------------------------------  --------------  ------
/home/pi/.local/lib/python2.7/site-packages  enum-compat     0.0.2
/home/pi/.local/lib/python2.7/site-packages  enum34          1.1.6
/home/pi/.local/lib/python2.7/site-packages  pexpect         4.2.1
/home/pi/.local/lib/python2.7/site-packages  ptyprocess      0.5.2
/home/pi/.local/lib/python2.7/site-packages  pygatt          3.2.0
/home/pi/.local/lib/python2.7/site-packages  pyserial        3.4
/usr/local/lib/python2.7/dist-packages       bluepy          1.1.1
/usr/local/lib/python2.7/dist-packages       click           6.7
/usr/local/lib/python2.7/dist-packages       click-datetime  0.2
/usr/local/lib/python2.7/dist-packages       construct       2.8.21
/usr/local/lib/python2.7/dist-packages       pyaudio         0.2.11
/usr/local/lib/python2.7/dist-packages       tabulate        0.8.2
-------------------------------------------  --------------  ------

这样,您就可以很容易地辨别哪些包安装了sudo,哪些包没有安装sudo

注意:我注意到,当我通过sudo一次安装包,一次不安装包时,其中一个包优先,这样就不会列出另一个包(只显示一个位置)。我相信只有在本地目录中才会列出。这是可以改进的。


如果您安装了anaconda python发行版,您还可以使用

1
$conda list

除了上述解决方案之外。


有很多想法,最初我在思考这两个:

皮普

cons: not always installed

帮助(模块)

cons: output to console; with broken modules (see ubuntu...) can segfault

我需要一种简单的方法,使用基本库并与旧的python 2.x兼容

我看到了光:listmodules.py

在2.5的文档源目录中隐藏着一个小脚本,它列出了用于Python安装的所有可用模块。

优点:

uses only imp, sys, os, re, time

designed to run on Python 1.5.2 and newer

the source code is really compact, so you can easy tinkering with it, for example to pass an exception list of buggy modules (don't try to import them)


剥猫皮有很多方法。

最简单的方法是从外壳直接使用pydoc函数:pydoc modules

但要了解更多信息,请使用名为pip-date的工具,它还会告诉您安装日期。pip install pip-date

enter image description here


我需要找到默认情况下AWS Lambda中可用包的特定版本。我把这个页面上的想法混搭在一起。我把它分享给子孙后代。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pkgutil

__version__ = '0.1.1'

def get_ver(name):
    try:
        return str(__import__(name).__version__)
    except:
        return None

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'body': [{
                   'path': m.module_finder.path,
                   'name': m.name,
                   'version': get_ver(m.name),
                 } for m in list(pkgutil.iter_modules())
                 #if m.module_finder.path =="/var/runtime" # Uncomment this if you only care about a certain path
                ],
    }

我发现提供的boto3库已经过时了,我的代码失败并不是我的错。我只需要在我的项目中添加boto3和botocore。但是,如果没有这个,我可能会认为我的代码很糟糕。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
{
 "statusCode": 200,
 "body": [
    {
     "path":"/var/task",
     "name":"lambda_function",
     "version":"0.1.1"
    },
    {
     "path":"/var/runtime",
     "name":"bootstrap",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"boto3",
     "version":"1.9.42"
    },
    {
     "path":"/var/runtime",
     "name":"botocore",
     "version":"1.12.42"
    },
    {
     "path":"/var/runtime",
     "name":"dateutil",
     "version":"2.7.5"
    },
    {
     "path":"/var/runtime",
     "name":"docutils",
     "version":"0.14"
    },
    {
     "path":"/var/runtime",
     "name":"jmespath",
     "version":"0.9.3"
    },
    {
     "path":"/var/runtime",
     "name":"lambda_runtime_client",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"lambda_runtime_exception",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"lambda_runtime_marshaller",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"s3transfer",
     "version":"0.1.13"
    },
    {
     "path":"/var/runtime",
     "name":"six",
     "version":"1.11.0"
    },
    {
     "path":"/var/runtime",
     "name":"test_bootstrap",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"test_lambda_runtime_client",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"test_lambda_runtime_marshaller",
     "version": null
    },
    {
     "path":"/var/runtime",
     "name":"urllib3",
     "version":"1.24.1"
    },
    {
     "path":"/var/lang/lib/python3.7",
     "name":"__future__",
     "version": null
    },
...

我发现的也和他们官方公布的不一样。在撰写本文时:

Operating system – Amazon Linux
AMI – amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2
Linux kernel – 4.14.77-70.59.amzn1.x86_64
AWS SDK for JavaScript – 2.290.0\
SDK for Python (Boto 3) – 3-1.7.74 botocore-1.10.74


从壳

1
ls site-packages

如果没有帮助,你可以这样做。

1
2
3
4
import sys
import os
for p in sys.path:
    print os.listdir( p )

看看会产生什么。