如何确定模块名称是否是python标准库

时间:2017-09-27 07:08:26

标签: python python-2.7

我有一个模块名称作为字符串(例如' logging'),它是通过查询对象的模块属性给出的。

如何区分属于我的项目的模块和属于python标准库的模块?

我知道我可以使用pip.get_installed_distributions()来检查这个模块是否是由pip安装的,但这些模块与标准库无关

注意:我正在使用python 2.7,因此仅在python 3.x中有效的解决方案不太相关。

与答案here不同,我一直在寻找一种可以在O(1)中运行的解决方案,不需要保存结果数组,也不需要为每个查询扫描目录。

感谢。

4 个答案:

答案 0 :(得分:3)

使用标准模块imp快速解决脏问题:

    import imp
    import os.path
    import sys

    python_path = os.path.dirname(sys.executable)

    my_mod_name = 'logging'

    module_path = imp.find_module(my_mod_name)[1]
    if 'site-packages' in module_path or python_path in module_path or not imp.is_builtin(my_mod_name):
        print('module', my_mod_name, 'is not included in standard python library')

答案 1 :(得分:2)

修改

我使用了here的解决方案。

import distutils.sysconfig as sysconfig
import os

def std_modules():
    ret_list = []
    std_lib = sysconfig.get_python_lib(standard_lib=True)
    for top, dirs, files in os.walk(std_lib):
        for nm in files:
            if nm != '__init__.py' and nm[-3:] == '.py':
                ret_list.append(os.path.join(top, nm)[len(std_lib)+1:-3].replace('\\','.'))
    return ret_list

l = std_modules()
print("logging" in l)
print("os" in l)

输出:

False
True

这适用于Python 2和Python 3。

编辑前:

我想,您可以使用Python文档。以下是Python 2 DocsPython 3 Docs的标准库部分。此外,您可以选择Python的确切版本。

答案 2 :(得分:0)

此帖子的旧副本中也有一个很好的答案:https://stackoverflow.com/a/28873415/7262247

这是您可以执行的操作:

from stdlib_list import stdlib_list
import sys

all_stdlib_symbols = stdlib_list('.'.join([str(v) for v in sys.version_info[0:2]]))

module_name = 'collections'

if module_name in all_stdlib_symbols:
    print("%s is in stdlib" % module_name)

答案 3 :(得分:0)

以上所有解决方案都不是我想要的,所以我又做了另一种方式。在这里张贴,以防对任何人有用。

import os

def standard_lib_names_gen(include_underscored=False):
    standard_lib_dir = os.path.dirname(os.__file__)
    for filename in os.listdir(standard_lib_dir):
        if not include_underscored and filename.startswith('_'):
            continue
        filepath = os.path.join(standard_lib_dir, filename)
        name, ext = os.path.splitext(filename)
        if filename.endswith('.py') and os.path.isfile(filepath):
            if str.isidentifier(name):
                yield name
        elif os.path.isdir(filepath) and '__init__.py' in os.listdir(filepath):
            yield name
>>> standard_lib_names = set(standard_lib_names_gen(include_underscored=True))
>>> # verify that a few known libs are there (including three folders and three py files)
>>> assert {'collections', 'asyncio', 'os', 'dis', '__future__'}.issubset(standard_lib_names)
>>> # verify that other decoys are not in there
>>> assert {'__pycache__', 'LICENSE.txt', 'config-3.8-darwin', '.DS_Store'}.isdisjoint(standard_lib_names)
>>>
>>> len(standard_lib_names)
200
>>>
>>> # not including underscored
>>> standard_lib_names = set(standard_lib_names_gen(include_underscored=False))
>>> len(standard_lib_names)
184