基于属性的hydra结构化配置中的属性转换器



是否可以在基于attr.s的hydra-结构化配置中使用转换器

我尝试了这个最小的例子:

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()
# Registering the Config class with the name 'config'.
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}

虽然在python解释器中直接实例化Times10Config确实会导致预期的行为:

In [5]: Times10Config(num=1)
Out[5]: Times10Config(num=10)

OmegaConf不实例化底层对象,只是将它们用作运行时验证的描述符。dataclass/attr类中定义的任何逻辑都未正常运行。

您可以使用OmegaConf.to_object((将配置结构转换为本机对象。请务必阅读OmegaConf.to_container((的文档。

在Hydra应用程序的上下文中,您可以在运行开始时转换您的配置:

@hydra.main(version_base=None, config_name="config")
def my_app(cfg: Times10Config) -> None:
cfg = OmegaConf.to_object(cfg)
print(cfg)

不是自动的,但您可以添加此行:

cfg = Times10Config(**cfg)

从传递给hydra.main修饰函数的对象中实例化config类的对象,如果你想真正获得你定义的类的config对象,并拥有所有正常的attrs机制(验证器、转换器等(。但是hydra传递的对象实际上只是一个DictConfig对象,该类型注释只是用来让静态类型检查器验证配置对象的属性。

最新更新