You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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'])

工作原理

  1. 用ast.parse将代码转换为语法树,遍历所有类定义节点
  2. 检查每个类的装饰器列表,判断是否存在manager.register形式的装饰器
  3. 对未匹配到的类,输出指定格式的提示信息

运行时检查方案

如果代码中存在动态注册类的场景,静态分析可能遗漏,此时可以通过运行代码并对比已注册类来排查。

实现代码(需配合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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 22:45:03