确定给定的Python模块是否是内置模块

我正在对各种模块进行一些解析和内省,但我不想解析内置模块。现在,内置模块没有特殊类型,比如有一个
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__')
是检查模块是否内置的方法?当然,it4ѭ并不常见,但有没有更坚实的方法来确定模块是否内置?     
已邀请:
sys.builtin_module_names
  一个字符串元组给出的名称   编译成的所有模块   这个Python解释器。 (这个   任何信息都不可用   其他方式 - modules.keys()仅列出   导入的模块。)     
您可以使用
imp.is_builtin
查看模块名称是否与内置模块匹配,但我无法想到任何可靠地内省模块对象的方法。 您也可以尝试以下方法:
>>> import imp
>>> f, path, desc = imp.find_module("sys")
>>> desc
('', '', 6)
>>> desc[2] == imp.C_BUILTIN
True
    
当你说“内置”,你的意思是,用C语言写的,或者你的意思是,标准库的一部分?如果你的意思是第一个,那么寻找
__file__
是正确的做法。正如您所看到的,即使是Python解释器也使用
__file__
作为内置函数的指示。 如果您的意思是“标准库的一部分”,那么很难确定。     
如果您只是按照要求考虑,
builtins
,那么接受的答案显然是正确的。 就我而言,我也在寻找标准库,我指的是一个给定Python发行版附带的所有可导入模块的列表。关于这方面的问题已被多次询问,但我找不到包含我正在寻找的所有内容的答案。 我的用例是在Python
import x
声明中将任意
x
作为: 包含在Python stdlib +内置插件中 作为第三方模块安装 也不 这适用于virtualenvs或全局安装。它查询运行脚本的任何python二进制文件的分布。最后的块确实达到了virtualenv,但我认为这是理想的行为。
# 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
获取常规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
和其他一些可选模块。
top_level_libs
distutils.sysconfig.get_python_lib(standard_lib=True)
调用返回平台无关标准库的顶级目录。 这些很容易被遗漏,因为它们可能不会与其他模块位于相同的python路径下。如果您使用OSX并运行virtualenv,则实际上将从系统安装中导入这些模块。这些模块包括
email
logging
xml
等等。 结论 对于我的2013 MacBookPro,我发现了modules38ѭ安装的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
我提出了代码和输出的要点。如果你认为我错过了一个课程或者包含了一个虚假的模块,我想听听它。 * 备择方案 在撰写这篇文章时,我挖了
pip
setuptools
API。这些信息可能通过单个模块进行,但您确实需要了解该API的方法。 在我开始之前,我被告知
six
具有专门针对此问题的功能。有意义的可能存在,但我自己找不到它。     

要回复问题请先登录注册