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

如何在Python的settrace中判断call事件是否为类定义?

用settrace追踪类定义的可行方案

核心思路:依托CPython类定义的底层实现

CPython中类定义语句本质是调用__build_class__函数,这是判断进入类定义最可靠的切入点,比解析字节码或常量更直接。

具体实现方案

  • Hook __build_class__配合追踪标记:
    启动追踪前替换全局__build_class__,在类定义执行前后设置状态标记,在settrace的call事件中检查该标记即可:
    import sys
    
    _original_build_class = __build_class__
    _is_defining_class = False
    
    def hooked_build_class(func, name, *bases, **kwargs):
        global _is_defining_class
        _is_defining_class = True
        try:
            return _original_build_class(func, name, *bases, **kwargs)
        finally:
            _is_defining_class = False
    
    __build_class__ = hooked_build_class
    
    def trace_callback(frame, event, arg):
        if event == 'call':
            if _is_defining_class:
                print(f"进入类定义: {frame.f_code.co_name}")
        return trace_callback
    
    sys.settrace(trace_callback)
    
    # 测试示例
    class DemoClass:
        pass
    
  • 直接在call事件中遍历调用栈:
    无需hook函数,在call事件回调里向上遍历调用栈,检查是否存在__build_class__的调用帧:
    import sys
    
    def trace_callback(frame, event, arg):
        if event == 'call':
            caller_frame = frame.f_back
            while caller_frame:
                if caller_frame.f_code.co_name == '__build_class__':
                    print(f"进入类定义: {frame.f_code.co_name}")
                    break
                caller_frame = caller_frame.f_back
        return trace_callback
    
    sys.settrace(trace_callback)
    
    # 测试示例
    class DemoClass:
        pass
    

方案优势

  • 避开解析co_consts的不确定性:字节码常量可能包含无关内容,且不同Python版本的常量结构可能有差异,可靠性差。
  • 无需依赖无意义的co_flags:co_flags没有专门标记类定义的位,无法区分普通函数与类的构造代码块,用它判断完全不可行。

内容的提问来源于stack exchange,提问作者Austin Cory Bart

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 06:45:13