统计Python标准库的对象与方法数量及相关技术咨询
Python标准库对象与方法统计问题及解决方案
问题背景
为对比不同语言标准库的对象与方法数量,我编写了如下Python脚本统计特定Python 3.x环境下标准库的相关数量:
from sys import stdlib_module_names from inspect import isclass from importlib import import_module modules = stdlib_module_names - {'this', 'antigravity'} col = [] for m in modules: try: col.append(dir(import_module(m))) except: pass col = {item for sublist in col for item in sublist} cnt = 0 for thing in col: try: if isclass(eval(thing)): cnt += len(dir(thing)) except: pass print(cnt + len(col))
但运行时发现dir()函数的结果不稳定:
- 命令行执行
python script.py,结果在14075到14092之间波动; - VSCode REPL中,第一次和第二次运行结果不同,后续运行结果与第二次一致。
技术问题
- 当前得到的结果是否大致正确?
- 是否存在一种稳定的方法来统计
stdlib_module_names中的函数与方法数量?
解答
1. 当前结果是否大致正确?
当前结果只能算粗略近似值,和真实标准库API数量有明显偏差,问题出在这些地方:
dir()会返回模块动态生成的属性、内部特殊方法(如__init__),甚至加载时的临时对象,这类内容不稳定且不属于对外暴露的核心API;eval(thing)存在作用域问题,很多模块内的对象无法在全局作用域解析,触发异常后被跳过,导致统计遗漏;- 用集合去重会把不同模块的同名对象合并,但它们是独立的API,统计逻辑错误;
- 部分依赖系统环境的标准库模块(如
fcntl、msvcrt)无法导入,直接被try-except跳过,统计范围不完整。
2. 稳定的统计方法
要得到稳定准确的结果,需避开dir()的动态特性,直接分析模块静态成员,优化后的脚本如下:
import inspect from sys import stdlib_module_names from importlib import import_module # 排除非核心演示模块 exclude_modules = {'this', 'antigravity'} modules = [m for m in stdlib_module_names if m not in exclude_modules] total_top_level = 0 # 顶层类、函数数量 total_class_methods = 0 # 类的方法数量 for module_name in modules: try: module = import_module(module_name) # 遍历模块成员,过滤内部特殊属性 for name, member in inspect.getmembers(module): if name.startswith('__') and name.endswith('__'): continue # 统计顶层类和函数 if inspect.isclass(member) or inspect.isfunction(member): total_top_level += 1 # 统计类的非特殊方法 if inspect.isclass(member): for cls_name, cls_member in inspect.getmembers(member): if cls_name.startswith('__') and cls_name.endswith('__'): continue if inspect.ismethod(cls_member) or inspect.isfunction(cls_member): total_class_methods += 1 except Exception as e: print(f"无法导入模块 {module_name}: {str(e)}") continue print(f"标准库顶层对象数量(类+函数):{total_top_level}") print(f"标准库类的方法数量:{total_class_methods}") print(f"总数量:{total_top_level + total_class_methods}")
关键优化点
- 用
inspect.getmembers()替代dir(),直接获取成员对象,避免eval()的作用域问题; - 过滤以
__开头结尾的内部特殊成员,只统计对外暴露的API; - 明确区分类、函数、方法的类型,避免重复或错误统计;
- 保留无法导入模块的报错信息,便于确认统计范围;
- 取消去重逻辑,不同模块的同名对象是独立API,分别统计。
稳定性说明
该脚本结果稳定,因为:
- 只统计模块静态成员,不受动态加载的临时属性影响;
- 过滤规则明确,排除了随机波动的内部内容;
- 遍历逻辑严谨,不会因作用域问题遗漏或错误解析对象。
内容的提问来源于stack exchange,提问作者Donald Seinen
相关产品推荐
相关产品推荐

