<p>如果你认为它只是被问到,<code>builtins</code>,那么接受的答案显然是正确的。在</p>
<p>在我的例子中,我也在寻找标准库,我指的是给定Python发行版附带的所有可导入模块的列表。关于这方面的问题已经被问了好几次,但我找不到一个包括我所寻找的一切的答案。在</p>
<p>我的用例是在Python <code>import x</code>语句中插入任意一个<code>x</code>,如下所示:</p>
<ul>
<li>包含在Python stdlib+内置组件中</li>
<li>作为第三方模块安装</li>
<li>都不是</li>
</ul>
<p>这将适用于virtualenvs或全局安装。它查询运行脚本的任何python二进制文件的分布。最后一块确实超出了virtualenv,但我认为这是期望的行为。在</p>
<pre><code># You may need to use setuptools.distutils depending on Python distribution.
import distutils
import glob
import os
import pkgutil
import sys
def get_python_library():
# Get list of the loaded source modules on sys.path.
modules = {
module
for _, module, package in list(pkgutil.iter_modules())
if package is False
}
# Glob all the 'top_level.txt' files installed under site-packages.
site_packages = glob.iglob(os.path.join(os.path.dirname(os.__file__)
+ '/site-packages', '*-info', 'top_level.txt'))
# Read the files for the import names and remove them from the modules list.
modules -= {open(txt).read().strip() for txt in site_packages}
# Get the system packages.
system_modules = set(sys.builtin_module_names)
# Get the just the top-level packages from the python install.
python_root = distutils.sysconfig.get_python_lib(standard_lib=True)
_, top_level_libs, _ = list(os.walk(python_root))[0]
return sorted(top_level_libs + list(modules | system_modules))
</code></pre>
<p><strong>返回</strong></p>
<p>已排序的导入列表:<code>[..., 'imaplib', 'imghdr', 'imp', 'importlib', 'imputil', 'inspect', 'io', ...]</code></p>
<p><strong>说明</strong>:</p>
<p>我把它分成几块,这样每个小组需要的原因就可以很清楚了。在</p>
<ul>
<li><p><code>modules</code></p>
<ul>
<li><a href="https://docs.python.org/2.7/library/pkgutil.html#pkgutil.iter_modules" rel="nofollow noreferrer">^{<cd6>}</a>调用扫描<code>sys.path</code>上所有加载的模块,并返回<code>(module_loader, name, ispkg)</code>元组的生成器。在</li>
<li>我把它转换成一个集合并过滤出包,因为这里我们只关心源模块。在</li>
</ul></li>
<li><p><code>site_packages</code></p>
<ul>
<li>获取常规站点包目录下所有已安装包的列表,并从<code>modules</code>列表中删除它们。这大致相当于第三方DEP。在</li>
<li>这是最难纠正的部分。很多东西几乎都起作用了,比如<a href="https://stackoverflow.com/questions/31544003/different-list-of-installed-packages-sing-pip-list-and-pip-get-installed-dist">^{<cd11>}</a>或{<cd12>}。但是<code>pip</code>返回的模块名称与PyPi上的一样,而不是导入到源文件中时的名称。某些病理包裹会从裂缝中滑出,比如:
<ul>
<li><code>requests-futures</code>作为<code>requests_futures</code>导入。在</li>
<li><code>colors</code>,这实际上是PyPi上的{<cd17>},因此混淆了任何合理的启发式。在</li>
</ul></li>
<li>我确信某些低使用率模块在其包中不包括<code>top_level.txt</code>。我的所有案例都被正确配置了。在</li>
</ul></li>
<li><p><code>system_modules</code></p>
<ul>
<li>如果不显式地请求它们,就不会得到这些系统模块,比如<code>sys</code>、<code>gc</code>、<code>errno</code>和其他一些{a3}。在</li>
</ul></li>
<li><p><code>top_level_libs</code></p>
<ul>
<li><a href="https://docs.python.org/2/distutils/apiref.html#distutils.sysconfig.get_python_lib" rel="nofollow noreferrer">^{<cd24>}</a>调用返回独立于平台的标准库的顶层目录。在</li>
<li>它们很容易丢失,因为它们可能与其他模块不在同一python路径下。如果您在OSX上运行virtualenv,这些模块实际上将从系统安装中导入。这些模块包括<code>email</code>、<code>logging</code>、<code>xml</code>等。在</li>
</ul></li>
</ul>
<p><strong>结论</strong></p>
<p>对于我的2013 MacBookPro,我找到了403个模块用于<code>python2.7</code>安装。在</p>
^{pr2}$
<p>我提出了<a href="https://gist.github.com/mateor/89a9cef41532021549739a12eae7790a" rel="nofollow noreferrer">the code and output</a>的要点。如果你认为我错过了一个类或包含了一个伪造的模块,我想听听。在</p>
<p><strong>*备选方案</strong></p>
<ul>
<li><p>在写这篇文章时,我对<code>pip</code>和{<cd30>}API进行了深入的研究。这些信息可能通过单个模块传递,但您确实需要了解如何绕过该API。</p></li>
<li><p>在我开始之前,有人告诉我,<code>six</code>有一个专门针对这个问题的函数。它可能存在,但我自己找不到。</p></li>
</ul>