Python多继承logger类报错AttributeError:'au'对象无logger属性求助
问题分析与解决:AttributeError: 'au' object has no attribute 'logger'
问题根源
- 多继承MRO机制限制:
au类继承顺序为(auth, logger),Python中super().__init__()会按方法解析顺序(MRO)仅调用第一个父类auth的构造方法,而auth的__init__是空实现,完全没触发logger类的初始化逻辑。self.logger是在logger的__init__中定义的,未执行该方法自然不存在这个属性。 - 构造方法参数缺失:即便要调用
logger的__init__,它还需要corr和log_set两个必传参数,直接调用时必须提供有效值。
修复方案
在au类的构造方法中,显式调用logger类的__init__方法并传入必要参数,确保日志初始化逻辑被执行。同时修正auth类中validate_settings方法遗漏的self参数(否则调用该方法会报错)。
修改后的完整代码
import logging import os from pathlib import Path import datetime import json class logger: def __init__(self, corr, log_set) -> None: self.logger = logging.getLogger() self.logger.setLevel(logging.DEBUG) if self.logger.hasHandlers(): self.logger.handlers.clear() log_file_path = os.path.join( Path(__file__).parent.parent, f'python_{datetime.datetime.now().strftime("%Y-%m-%d")}.log' ) file_handler = logging.FileHandler(log_file_path) stream_handler = logging.StreamHandler() log_set['corr'] = corr format_str = { "timestamp": "%(asctime)s", "loglevel": "%(levelname)s", "process": "myProcess", "source": "Me", "name": "Mike", "logger": "%(funcName)s", "message": "%(message)s" } format_str.update(log_set) format_str = json.dumps(format_str) stream_formatter = logging.Formatter(format_str) file_formatter = logging.Formatter(format_str) file_handler.setFormatter(file_formatter) stream_handler.setFormatter(stream_formatter) self.logger.addHandler(file_handler) self.logger.addHandler(stream_handler) def shutdown_logger(self, logger): logger.handlers.clear() logger.shutdown() class auth: def __init__(self) -> None: pass def validate_settings(self): # 补充缺失的self参数 pass class au(auth, logger): def __init__(self) -> None: super().__init__() # 调用auth的构造方法 # 显式调用logger的构造方法,传入必要参数 corr = "default_corr_id" # 可根据业务逻辑生成或传入 log_set = {} # 初始日志配置字典,可自定义字段 logger.__init__(self, corr, log_set) def set_headers(self, headers): self.logger.info("starting something") if headers == 'default': header = {'Content-Type': 'application/x-www-form-urlencoded'} else: header = headers return header a = au() print(a.set_headers("default"))
额外说明
- 若多继承场景更复杂,也可借助
super()结合MRO特性调用所有父类构造方法,但显式调用目标父类__init__在该场景下更直观、不易出错。 corr和log_set参数需根据实际业务需求赋值,示例中为占位符,可改为动态生成或外部传入的方式。
内容的提问来源于stack exchange,提问作者qwerty
相关产品推荐
相关产品推荐

