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

确定给定Python模块是否为内置模块,python,module,internals,python-internals,Python,Module,Internals,Python Internals,我正在对各种模块进行解析和内省,但我不想解析内置模块。现在,内置模块没有特殊的类型,比如有一个类型.BuiltinFunctionType,那么我该怎么做呢 >>> import CornedBeef >>> CornedBeef <module 'CornedBeef' from '/meatish/CornedBeef.pyc'> >>> CornedBeef.__file__ '/meatish/CornedBeef.pyc

我正在对各种模块进行解析和内省,但我不想解析内置模块。现在,内置模块没有特殊的类型,比如有一个
类型.BuiltinFunctionType
,那么我该怎么做呢

>>> import CornedBeef
>>> CornedBeef
<module 'CornedBeef' from '/meatish/CornedBeef.pyc'>
>>> CornedBeef.__file__
'/meatish/CornedBeef.pyc'
>>> del CornedBeef.__file__
>>> CornedBeef
<module 'CornedBeef' (built-in)>
>>进口咸牛肉
>>>咸牛肉
>>>咸牛肉__
“/肉味/咸牛肉,pyc”
>>>玉米牛肉__
>>>咸牛肉
根据Python的说法,如果模块没有
\uuuu file\uuu
属性,那么它显然是内置的。这是否意味着
hasattr(SomeModule,'.'文件'.'.'是检查模块是否内置的方法?当然,del SomeModule.\uuuuu file\uuuuu
并不常见,但有没有更可靠的方法来确定模块是否内置?

当你说“内置”时,你是指用C编写的,还是指标准库的一部分?如果您指的是第一个,那么查找
\uuuu文件\uuuu
是正确的做法。正如您所看到的,甚至Python解释器也使用
\uuuuu文件\uuuu
的存在作为内置性的指示器


如果您的意思是“标准库的一部分”,那么很难确定。

您可以使用
imp.is_builtin
查看模块名称是否与内置模块匹配,但我想不出任何方法来可靠地内省模块对象

您还可以尝试以下操作:

>>> import imp
>>> f, path, desc = imp.find_module("sys")
>>> desc
('', '', 6)
>>> desc[2] == imp.C_BUILTIN
True
一个字符串元组,给出 编译为的所有模块 这是Python解释器。(本 没有任何形式的信息 另一种方式-modules.keys()仅列出 导入的模块。)


如果你简单地考虑它,<代码> BuugItIs<代码>,那么所接受的答案显然是正确的。

在我的例子中,我也在寻找标准库,我指的是给定Python发行版附带的所有可导入模块的列表。关于这一点的问题已经被问了好几次,但我找不到一个包括我所寻找的一切的答案

我的用例是在Python
import x
语句中使用任意
x
作为:

  • 包含在Python stdlib+内置程序中
  • 作为第三方模块安装
  • 都不是
这将适用于VirtualNVS或全局安装。它查询运行脚本的任何python二进制文件的分发。最后的块确实达到了ValueLeNV,但是我认为期望的行为。< /P>
# 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))
返回

导入的排序列表:
[…,'imaplib','imghdr','imp','importlib','imputil','inspect','io',…]

说明

我把它分成几块,这样每个小组需要的原因就可以很清楚了

  • 模块

    • 该调用扫描
      sys.path
      上所有加载的模块,并返回
      的生成器(module\u loader,name,ispkg)
      元组
    • 我将它转换为一个集合并过滤掉包,因为这里我们只关心源模块
  • site\u包

    • 在常规站点软件包目录下获取所有已安装软件包的列表,并将其从
      模块
      列表中删除。这大致相当于第三方DEP
    • 这是最难纠正的部分。很多事情几乎都成功了,比如或
      站点
      。但是,
      pip
      返回模块名,与PyPi上的模块名相同,而不是与导入到源文件时的模块名相同。某些病理性包裹会从裂缝中滑落,如:
      • 请求期货
        作为
        请求期货
        导入
      • 颜色
        ,实际上是PyPi上的
        ansicolors
        ,因此混淆了任何合理的启发式
    • 我确信某些低使用率模块的软件包中不包含
      top_level.txt
      。但这涵盖了我100%的用例,似乎对所有正确配置的东西都有效
  • 系统模块

    • 如果您没有明确要求,您将无法获得这些系统模块,如
      sys
      gc
      errno
      和其他一些模块
  • top\u level\u libs

    • 该调用返回独立于平台的标准库的顶级目录
    • 这些模块很容易丢失,因为它们可能与其他模块不在相同的python路径下。如果您在OSX上运行virtualenv,这些模块实际上将从系统安装中导入。这些模块包括
      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
我写了一篇文章的大意。如果你认为我错过了一节课或者包含了一个假的模块,我很想听听

*备选方案

  • 在写这篇文章时,我深入研究了
    pip
    setuptools
    API。这些信息可能通过单个模块传输,但您确实需要了解API的使用方法

  • 在我开始之前,有人告诉我,
    six
    有一个专门针对这个问题的函数。这是有道理的,可能存在,但我自己找不到


内置有不止一个含义:1)随python解释器一起提供2)编译到cpython解释器中。更有用的含义是1,但这个答案只适用于2。@bukzor:不要混淆“内置”和“stdlib”模块。显然,
sys.内置模块名称
不是特定于CPython的。