por*_*uod 18 python module internals python-internals
我正在对各种模块进行一些解析和内省,但我不想解析内置模块.现在,内置模块没有特殊类型,就像有一个types.BuiltinFunctionType,所以我该怎么做?
>>> import CornedBeef
>>> CornedBeef
<module 'CornedBeef' from '/meatish/CornedBeef.pyc'>
>>> CornedBeef.__file__
'/meatish/CornedBeef.pyc'
>>> del CornedBeef.__file__
>>> CornedBeef
<module 'CornedBeef' (built-in)>
Run Code Online (Sandbox Code Playgroud)
根据Python,如果模块没有__file__属性,它显然是内置的.这是否意味着hasattr(SomeModule, '__file__')检查模块是否内置的方法是什么?当然,它并不常见del SomeModule.__file__,但有没有更坚实的方法来确定模块是否内置?
sys.builtin_module_names一个字符串元组,给出了编译到此Python解释器中的所有模块的名称.(此信息不以任何其他方式提供 - modules.keys()仅列出导入的模块.)
如果您认为它只是被问到builtins,那么接受的答案显然是正确的。
就我而言,我也在寻找标准库,我指的是给定 Python 发行版附带的所有可导入模块的列表。已经多次提出有关此问题的问题,但我找不到包含我正在寻找的所有内容的答案。
我的用例是x将 Pythonimport x语句中的任意一个分桶为:
这适用于 virtualenvs 或全局安装。它查询运行脚本的任何 python 二进制文件的分布。最后一个块确实超出了 virtualenv,但我认为这是所需的行为。
# You may need to use setuptools.distutils depending on Python distribution (from setuptools import distutils)
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))
Run Code Online (Sandbox Code Playgroud)
退货
进口的排序列表: [..., 'imaplib', 'imghdr', 'imp', 'importlib', 'imputil', 'inspect', 'io', ...]
说明:
我把它分成了几块,所以需要每个组的原因就很清楚了。
modules
pkgutil.iter_modules调用扫描所有加载的模块sys.path并返回一个(module_loader, name, ispkg)元组生成器。site_packages
modules列表,并将它们从列表中删除。这大致对应于第三方 deps。pip.get_installed_distributions或site。但是pip返回模块名称,就像它们在 PyPi 上一样,而不是像导入到源文件时那样。某些病理包会从裂缝中溜走,例如:
requests-futures导入为requests_futures.colors,这实际上是ansicolors在 PyPi 上,因此混淆了任何合理的启发式方法。top_level.txt在他们的包中。但这涵盖了我 100% 的用例似乎适用于正确配置的所有内容。system_modules
sys,gc,errno和一些其他的可选模块。top_level_libs
distutils.sysconfig.get_python_lib(standard_lib=True)调用返回平台独立标准库的顶级目录。email,logging,xml和几个。结论
对于我的 2013 年 MacBookPro,我找到了 403 个用于python2.7安装的模块。
>>> print(sys.version)
2.7.10 (default, Jul 13 2015, 12:05:58)
[GCC 4.2.1 Compatible Apple LLVM 6.1.0 (clang-602.0.53)]
>>> print(sys.hexversion)
34015984
>>> python_stdlib = get_python_libirary()
>>> len(python_stdlib)
403
Run Code Online (Sandbox Code Playgroud)
我提出了代码和输出的要点。如果您认为我遗漏了一个课程或包含了一个虚假模块,我想听听。
* 备择方案
在写这篇文章时,我挖掘了pip和setuptoolsAPI。这些信息可能通过单个模块提供,但您确实需要了解该 API 的方法。
在我开始之前,有人告诉我six有一个专门针对这个问题的功能。这可能存在是有道理的,但我自己找不到。