我有一个模块名称作为字符串(例如' logging'),它是通过查询对象的模块属性给出的。
如何区分属于我的项目的模块和属于python标准库的模块?
我知道我可以使用pip.get_installed_distributions()来检查这个模块是否是由pip安装的,但这些模块与标准库无关
注意:我正在使用python 2.7,因此仅在python 3.x中有效的解决方案不太相关。
与答案here不同,我一直在寻找一种可以在O(1)中运行的解决方案,不需要保存结果数组,也不需要为每个查询扫描目录。
感谢。
答案 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 Docs和Python 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