基于attr.s的Hydra结构化配置能否使用converters?
在Hydra的attr.s结构化配置中使用converters的问题
问题描述
尝试在Hydra的attr.s结构化配置中使用converter,编写了如下示例代码:
import hydra from hydra.core.config_store import ConfigStore import attr @attr.s class Times10Config: num: int = attr.ib(default=42, converter=lambda x: x*10) cs = ConfigStore.instance() cs.store(name="config", node=Times10Config) @hydra.main(version_base=None, config_name="config") def my_app(cfg: Times10Config) -> None: print(cfg) if __name__ == "__main__": my_app()
运行命令python -m my_app num=1后,输出为{'num': 1},converter的转换逻辑未触发;但直接在Python解释器中实例化Times10Config(num=1)时,能得到预期结果Times10Config(num=10)。
原因分析
Hydra默认处理attrs结构化配置时,采用直接属性赋值的方式("structured"模式),而非调用类的构造函数,因此attr定义的converter不会被执行。
解决方法
方法1:强制Hydra通过构造函数实例化类
在注册配置到ConfigStore时,指定convert="instance"参数,让Hydra调用类的构造函数创建实例,从而触发converter:
cs.store(name="config", node=Times10Config, convert="instance")
修改后重新运行命令,输出会变为Times10Config(num=10),符合预期。
方法2:使用attrs的__attrs_post_init__钩子
在类中添加__attrs_post_init__方法,手动执行转换逻辑。该方法会在实例创建完成后自动执行,不受Hydra实例化方式的影响:
@attr.s class Times10Config: num: int = attr.ib(default=42) def __attrs_post_init__(self): self.num *= 10
无论直接实例化还是通过Hydra加载配置,都会自动将num乘以10。
内容的提问来源于stack exchange,提问作者talz
相关产品推荐
相关产品推荐

