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

如何在父类方法中获取调用者的真实行号?

解决父类中获取真实调用者行号的问题

问题分析

你当前代码里用stack()[1]拿到的是直接调用父类info方法的栈帧——也就是子类Child中super().info(message)所在的行。当子类重写方法并转发调用到父类时,父类默认只能捕获到子类内部的调用行,而非业务代码中实际调用child.info()的行号。

解决方案

核心思路是遍历调用栈,跳过所有属于当前类(及子类)的方法调用,定位到第一个外部业务代码的调用栈帧。可以实现一个通用辅助函数来处理这个逻辑:

from inspect import getframeinfo, stack

def get_caller_frame():
    frames = stack()
    # 遍历栈帧,跳过Parent和Child类的内部调用
    for frame_info in frames:
        frame = frame_info[0]
        # 获取当前栈帧所属的类名(如果是类方法调用)
        class_name = frame.f_locals.get('self', None).__class__.__name__ if 'self' in frame.f_locals else None
        if class_name in ('Parent', 'Child'):
            continue
        # 找到第一个外部调用的栈帧后返回
        return frame
    # 兜底返回最后一个栈帧(极端情况备用)
    return frames[-1][0]

class Parent():
    def __init__(self):
        pass
    
    def info(self, message):
        caller = getframeinfo(get_caller_frame())
        print(caller.lineno)
    
class Child(Parent):
    def __init__(self):
        super().__init__()
    
    def info(self, message):
        super().info(message)

# 测试
child = Child()
child.info("test line")  # 现在会输出这一行的行号(比如第32行就输出32)
parent = Parent()
parent.info("test parent")  # 父类实例调用依然正常返回正确行号

针对AWS Lambda PowerTools日志库的适配

如果你是重写PowerTools的Logger类,逻辑完全通用:只需在日志记录的核心方法中,过滤掉日志类自身的调用栈帧,定位到业务代码的实际调用点。示例如下:

from inspect import getframeinfo, stack
from aws_lambda_powertools import Logger

class CustomLogger(Logger):
    def _get_caller_info(self):
        frames = stack()
        # 跳过日志类自身的调用(包括CustomLogger和父类Logger)
        target_classes = (self.__class__.__name__, Logger.__name__)
        for frame_info in frames:
            frame = frame_info[0]
            class_name = frame.f_locals.get('self', None).__class__.__name__ if 'self' in frame.f_locals else None
            if class_name in target_classes:
                continue
            caller = getframeinfo(frame)
            return caller.lineno, caller.filename
        # 兜底使用父类原有逻辑
        return super()._get_caller_info()

# 使用示例
logger = CustomLogger(service="my-service")
def lambda_handler(event, context):
    logger.info("Hello from Lambda")  # 日志会记录这一行的行号,而非CustomLogger内部调用行
    return {"message": "ok"}

内容的提问来源于stack exchange,提问作者Tamil selvan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 00:20:24