我正在对各种模块进行一些解析和内省,但我不想解析内置模块。现在,内置模块没有特殊类型,例如types.BuiltinFunctionType
,所以我该怎么做?
>>> import CornedBeef
>>> CornedBeef
<module 'CornedBeef' from '/meatish/CornedBeef.pyc'>
>>> CornedBeef.__file__
'/meatish/CornedBeef.pyc'
>>> del CornedBeef.__file__
>>> CornedBeef
<module 'CornedBeef' (built-in)>
根据Python,如果模块没有__file__
属性,那么它显然是内置的。这是否意味着hasattr(SomeModule, '__file__')
是检查模块是否内置的方法?当然,del SomeModule.__file__
并不常见,但有没有更坚实的方法来确定模块是否内置?
答案 0 :(得分:7)
sys.builtin_module_names
一个字符串元组,给出了名字 编译成的所有模块 这个Python解释器。 (这个 任何信息都不可用 其他方式 - modules.keys()仅列出 导入的模块。)
答案 1 :(得分:3)
您可以使用imp.is_builtin
查看模块名称是否与内置模块匹配,但我无法想到任何可靠地内省模块对象的方法。
您也可以尝试以下方法:
>>> import imp
>>> f, path, desc = imp.find_module("sys")
>>> desc
('', '', 6)
>>> desc[2] == imp.C_BUILTIN
True
答案 2 :(得分:2)
当你说“内置”时,你的意思是,用C语言编写,或者你的意思是,标准库的一部分?如果你的意思是第一个,那么寻找__file__
是正确的。正如您所看到的,即使是Python解释器也使用__file__
作为内置函数的指示符。
如果您的意思是“标准库的一部分”,那么很难确定。
答案 3 :(得分:2)
如果您只是按照builtins
的要求考虑,那么接受的答案显然是正确的。
就我而言,我也在寻找标准库,我指的是一个给定Python发行版附带的所有可导入模块的列表。关于这方面的问题曾多次被问过,但我找不到包含我所寻找的所有内容的答案。
我的用例是在Python x
语句中将任意import x
分成两部分:
这适用于virtualenvs或全局安装。它查询运行脚本的任何python二进制文件的分布。最后一个块确实达到了一个虚拟现实,但我认为这是理想的行为。
# 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))
<强>返回强>
已排序的导入列表:[..., 'imaplib', 'imghdr', 'imp', 'importlib', 'imputil', 'inspect', 'io', ...]
<强>解释强>:
我把它分成几块,所以每个小组需要的原因都很明确。
modules
pkgutil.iter_modules
调用会扫描sys.path
上所有已加载的模块,并返回(module_loader, name, ispkg)
元组的生成器。 site_packages
modules
列表中删除。这大致相当于第三方代表。pip.get_installed_distributions
或site
。但pip
返回模块名称,因为它们在PyPi上,而不是在导入到源文件时。某些病理包将穿过裂缝,如:
requests-futures
导入为requests_futures
。colors
,在PyPi上实际上是ansicolors
,因此会混淆任何合理的启发式。top_level.txt
。但这涵盖了100%的用例似乎适用于正确配置的所有内容。 system_modules
sys
,gc
,errno
以及其他{{3} }}。 top_level_libs
email
,logging
,xml
等等。<强>结论强>
对于我的2013 MacBookPro,我找到了python2.7
安装的403个模块。
>>> 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
我提出了distutils.sysconfig.get_python_lib(standard_lib=True)
的要点。如果你认为我错过了一个课程或者包含了一个虚假模块,我想听听它。
*替代方案
在写这篇文章时,我挖掘了pip
和setuptools
API。通过单个模块可能会提供此信息,但您确实需要了解该API的方式。
在开始之前,我被告知six
具有专门针对此问题的功能。它可能存在但我自己无法找到它。