如何检查模块/库/包是否是python标准库的一部分?

alv*_*vas 15 python module native package

我已经安装了很多带有pip的库/模块/包,现在我无法区分python标准库本身的哪个,哪些不是.当我的代码在我的机器上运行时,这会导致问题,但在其他任何地方都不起作用.

如何检查我在代码中导入的模块/库/包是否来自python stdlib?

假设检查是在具有所有外部库/模块/包的机器上完成的,否则我可以简单地在没有它们的其他机器上进行try-except导入.

例如,我确信这些导入可以在我的机器上运行,但是当它在只有普通Python安装的机器上时,它会中断:

from bs4 import BeautifulSoup
import nltk
import PIL
import gensim
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 8

您必须检查已导入的所有模块,以查看其中是否有任何模块位于标准库之外.

以下脚本不是防弹的,但应该给你一个起点:

import sys
import os

external = set()
exempt = set()
paths = (os.path.abspath(p) for p in sys.path)
stdlib = {p for p in paths
          if p.startswith((sys.prefix, sys.real_prefix)) 
          and 'site-packages' not in p}
for name, module in sorted(sys.modules.items()):
    if not module or name in sys.builtin_module_names or not hasattr(module, '__file__'):
        # an import sentinel, built-in module or not a real module, really
        exempt.add(name)
        continue

    fname = module.__file__
    if fname.endswith(('__init__.py', '__init__.pyc', '__init__.pyo')):
        fname = os.path.dirname(fname)

    if os.path.dirname(fname) in stdlib:
        # stdlib path, skip
        exempt.add(name)
        continue

    parts = name.split('.')
    for i, part in enumerate(parts):
        partial = '.'.join(parts[:i] + [part])
        if partial in external or partial in exempt:
            # already listed or exempted
            break
        if partial in sys.modules and sys.modules[partial]:
            # just list the parent name and be done with it
            external.add(partial)
            break

for name in external:
    print name, sys.modules[name].__file__
Run Code Online (Sandbox Code Playgroud)

把它作为一个新模块,在脚本中的所有导入导入它,它将打印它认为属于标准库的所有模块.


Bak*_*riu 5

标准库在python的文档中定义。您可以在那里搜索,或将模块名称放入列表并以编程方式进行检查。

或者,在 python3.4 中有一个新的隔离模式,允许忽略一定数量的用户定义的库路径。在以前版本的 python 中,您可以使用-s忽略每个用户的环境并-E忽略系统定义的变量。

在 python2 中,检查模块是否是标准库的一部分的一种非常简单的方法是清除sys.path

>>> import sys
>>> sys.path = []
>>> import numpy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named numpy
>>> import traceback
>>> import os
>>> import re
Run Code Online (Sandbox Code Playgroud)

但是这在 python3.3+ 中不起作用:

>>> import sys
>>> sys.path = []
>>> import traceback
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'traceback'
[...]
Run Code Online (Sandbox Code Playgroud)

这是因为从 python3.3 开始,导入机制发生了变化,导入标准库使用与导入任何其他模块相同的机制(请参阅文档)。

在 python3.3 中,确保只有 stdlib 的导入成功的唯一方法是仅将标准库路径添加到sys.path,例如:

>>> import os, sys, traceback
>>> lib_path = os.path.dirname(traceback.__file__)
>>> sys.path = [lib_path]
>>> import traceback
>>> import re
>>> import numpy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named 'numpy'
Run Code Online (Sandbox Code Playgroud)

我使用该traceback模块来获取库路径,因为这应该适用于任何系统。

对于作为stdlib 模块子集的内置模块,您可以检查sys.builtin_module_names