如何在Python模块中找出未被指定装饰器修饰的类与函数?
找出Python代码中未被指定装饰器修饰的类
静态分析方案(推荐批量扫描)
直接解析代码的抽象语法树(AST),无需运行代码即可排查未被manager.register装饰的类,适合大规模代码库扫描。
实现代码
import ast import os def find_undecorated_classes(file_path, target_managers): with open(file_path, 'r', encoding='utf-8') as f: code_ast = ast.parse(f.read()) for node in ast.walk(code_ast): if isinstance(node, ast.ClassDef): has_valid_decorator = False # 遍历类的所有装饰器 for decorator in node.decorator_list: # 匹配 manager.register 这类属性调用式装饰器 if isinstance(decorator, ast.Call) and isinstance(decorator.func, ast.Attribute): if decorator.func.attr == 'register' and decorator.func.value.id in target_managers: has_valid_decorator = True break if not has_valid_decorator: print(f"`{file_path}:`{node.name}` is undecorated by any manager") # 调用示例,传入目标文件路径和要检查的manager名称列表 find_undecorated_classes('/path/to/rules.py', ['manager'])
工作原理
- 用
ast.parse将代码转换为语法树,遍历所有类定义节点 - 检查每个类的装饰器列表,判断是否存在
manager.register形式的装饰器 - 对未匹配到的类,输出指定格式的提示信息
运行时检查方案
如果代码中存在动态注册类的场景,静态分析可能遗漏,此时可以通过运行代码并对比已注册类来排查。
实现代码(需配合RuleManager改造)
import importlib.util def check_runtime_registration(file_path, manager_name): # 动态导入目标模块 spec = importlib.util.spec_from_file_location('target_module', file_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) # 获取manager实例和已注册类集合 manager = getattr(module, manager_name) # 假设RuleManager的register方法维护了registered_classes属性存储已注册类 registered_classes = getattr(manager, 'registered_classes', set()) # 遍历模块中的所有类,对比未注册的 for name, obj in vars(module).items(): if isinstance(obj, type) and obj not in registered_classes: print(f"`{file_path}:`{name}` is undecorated by any manager") # 调用示例 check_runtime_registration('/path/to/rules.py', 'manager')
注意事项
需要修改RuleManager的register方法,在注册类时将其添加到registered_classes集合中,示例如下:
class RuleManager: def __init__(self): self.registered_classes = set() def register(self, cls): self.registered_classes.add(cls) return cls
两种方案对比
- 静态分析:无代码执行副作用,速度快,适合批量扫描,但无法识别动态注册的类
- 运行时检查:准确率更高,能覆盖动态场景,但会执行代码,可能触发副作用,需要依赖Manager类的内部实现
内容的提问来源于stack exchange,提问作者ijustlovemath
相关产品推荐
相关产品推荐

