PyYAML自定义构造类__init__方法无法访问嵌套实例属性问题
问题原因及修复方案
核心结论
你遇到的情况既不是配置遗漏也不是PyYAML的功能限制,是对PyYAML的嵌套节点解析逻辑和自定义构造器的使用方法有误导致的。
具体问题原因
__init__中嵌套参数为空、实例化后属性正常:PyYAML默认采用延迟解析策略处理嵌套节点,调用loader.construct_mapping()时如果没有传入deep=True参数,方法返回的字典中嵌套结构会先填充空容器占位,等顶层节点构造完成后再递归解析回填内容。你在__init__执行阶段拿到的就是还未填充的空容器,整个加载流程结束后嵌套值回填完成,所以__repr__可以读到正确值。__repr__返回类名变为YAML键名:这个属于自定义逻辑错误,大概率是你在构造器中错误地把YAML节点的tag、或者解析出来的映射键值赋值给了实例的__class__.__name__属性,或者没有显式调用PrintAttributes的构造方法,误用了PyYAML内部通用对象构造逻辑导致类名被覆盖。
修复方案
正确的自定义构造器写法
import yaml # 你的自定义类 class PrintAttributes: def __init__(self, a, b): self.a = a self.b = b def __repr__(self): # 显式写死类名,避免动态变量污染 return f"PrintAttributes(a={self.a}, b={self.b})" # 自定义构造器 def print_attr_constructor(loader, node): # 关键参数deep=True强制立即递归解析所有嵌套节点 params = loader.construct_mapping(node, deep=True) # 显式实例化,不要用动态赋值逻辑 return PrintAttributes(**params) # 注册构造器 yaml.add_constructor('!PrintAttributes', print_attr_constructor, Loader=yaml.FullLoader)
测试验证
nested_yaml = """ !PrintAttributes a: test b: key1: 嵌套值1 key2: 嵌套值2 """ res = yaml.load(nested_yaml, Loader=yaml.FullLoader) print(res) # 正常输出:PrintAttributes(a=test, b={'key1': '嵌套值1', 'key2': '嵌套值2'})
异常排查
如果调整后仍然出现类名异常,检查两处逻辑:
PrintAttributes的__repr__方法有没有错误引用外部动态变量- 构造器中有没有出现修改实例
__class__、__name__属性的逻辑
内容的提问来源于stack exchange,提问作者muxevola
相关产品推荐
相关产品推荐

