使用 Hydra 填充嵌套数据类对象

问题描述 投票:0回答:1

我有一个具有以下结构的 yaml 配置文件

paths:
    log: ./runs
    data: ./data
data:
    downloads: [
            {
                name: "1",
                url: "url_1",
                file: "file_1"
                },
            {
                name: "2",
                url: "url_2",
                file: "file_2"
                },
            {
                name: "3",
                url: "url_3",
                file: "file_3"
                }
            ]

我想将其加载到此配置数据类中:

@dataclass
class Config:
    paths: Paths
    data: Data

哪里

@dataclass
class Paths:
    log: str
    data: str


@dataclass
class Download:
    name: str
    url: str
    file: str

    def download(self):
        print("downloading")


@dataclass
class Data:
    downloads: list[Download]

这样我的配置中的每个“下载”字典都会填充一个下载数据类,然后我就可以调用下载方法。

在我的主要功能中,我有这样的东西:

cs = ConfigStore.instance()
cs.store(name="test_config", node=Config)


@hydra.main(version_base=None, config_path="configs", config_name="config")
def main(cfg: Config):
    for downloader in cfg.data.downloads:
        downloader.download()

当前配置结构对输入进行排序,但我没有获取对象的实例,只是字典,因此调用 download() 会引发错误。

我仍在了解 Hydra 的工作原理 - 是否真的可以返回填充的对象,或者我是否需要一些中间步骤来创建它们?

python configuration fb-hydra
1个回答
0
投票

您需要使用 instances 功能,使用特殊的键名

_target_=yourclass

此设置仅允许类型提示支持。虽然它们看起来像您的

Config (dataclass)
,但它是一个
DictConfig
对象,其结构类似于您的数据类。

您需要先使用 OmegaConf.to_container

structured_config_mode=SCMode.INSTANTIATE
将其转换为您的数据类

from omegaconf import OmegaConf, SCMode
for downloader in cfg.data.downloads:
    dc_downloader = OmegaConf.to_container(downloader,
                                           structured_config_mode=SCMode.INSTANTIATE
                                           resolve=True) # use resolve if you can
    dc_downloader.download()

您还可以查看 Hydra 的

instantiate
,了解更复杂的情况,您需要实例而不是 DictConfig 对象。

© www.soinside.com 2019 - 2024. All rights reserved.