我有一个具有以下结构的 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 的工作原理 - 是否真的可以返回填充的对象,或者我是否需要一些中间步骤来创建它们?
您需要使用 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()
instantiate
,了解更复杂的情况,您需要实例而不是 DictConfig 对象。