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

如何覆盖模块__name__属性,解决继承父类方法日志模块名不符问题

问题根因

a.py中的LOG是模块级日志器,在模块首次加载时就完成初始化,绑定了a模块的名称。父类A的方法运行时始终调用该日志器,因此即使是子类B调用父类方法,日志默认也会显示a模块的信息。

可行解决方案

方案1:重写父类方法,临时替换日志对象的名称属性

在b.py的子类B中重写对应方法,调用父类逻辑前后临时修改a.LOG的名称,调用完成后立即恢复,不会影响其他地方对A类的调用:

# b.py
import a

class B(a.A):
    def name(self):
        # 暂存原日志名
        original_log_name = a.LOG.name
        try:
            # 临时修改为当前模块名
            a.LOG.name = __name__
            # 调用父类原有逻辑
            super().name()
        finally:
            # 无论是否报错都恢复原日志名,避免影响其他调用
            a.LOG.name = original_log_name

该方案侵入性极低,仅影响B类调用对应方法时的日志输出,不会污染全局状态,适合单一场景使用。

方案2:给日志处理器添加自定义过滤器,动态修正模块名

如果需要批量处理所有继承自A的子类的日志输出,可以给对应日志器加过滤器,通过调用栈判断当前调用的类类型,动态替换模块名:

# 在项目日志初始化的位置添加如下过滤器
import logging
import inspect
import a

def fix_inherit_log_filter(record):
    stack = inspect.stack()
    for frame_info in stack:
        if frame_info.function == 'name' and 'a.py' in frame_info.filename:
            # 获取方法绑定的self实例
            self_obj = frame_info.frame.f_locals.get('self', None)
            if self_obj:
                # 替换为实例所属类对应的模块名
                record.name = self_obj.__class__.__module__
            break
    return True

# 给a模块的日志器添加过滤器
a.LOG.addFilter(fix_inherit_log_filter)

该方案适合子类数量多、需要统一处理的场景,不需要修改每个子类的方法。

方案3:全局替换a模块的LOG对象

如果B是A的唯一调用方,可以直接在导入a之后替换a.LOG为自定义的日志器:

# b.py
import a
import logging
# 替换a模块的LOG为b模块的日志器
a.LOG = logging.getLogger(__name__)

class B(a.A):
    pass

注意该方案会影响所有调用A类方法的日志输出,若存在其他直接调用A类的逻辑,日志也会显示为b模块的名称,仅适合B是A唯一调用方的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:27:04