Source code for torchrl.utils.config.config

from abc import ABCMeta
from collections import OrderedDict

import yaml
from yaml.representer import Representer

# Support for abstract classes
Representer.add_representer(ABCMeta, Representer.represent_name)


[docs]class Config: """ Configuration object used for initializing an Agent. It maintains the order from which the attributes have been set. Parameters ---------- configs: Keyword arguments Additional parameters that will be stored. Returns ------- Config object An object containing all configuration details (with possibly nested Config). """ def __init__(self, *args, **kwargs): # We want to maintain the order of the attributes, # this is especially necessary when defining NNs architectures self.__dict__["_attrs"] = OrderedDict() for i, value in enumerate(args): self._nested_loader("attr{}".format(i), value) for key, value in kwargs.items(): self._nested_loader(key, value) def __getattr__(self, value): try: return self.__dict__["_attrs"][value] except: raise AttributeError(value) def __setattr__(self, key, value): self.__dict__["_attrs"][key] = value def __repr__(self): return yaml.dump(self.as_dict(), default_flow_style=False) def __iter__(self): yield from self.as_dict() def _nested_loader(self, key, value): if isinstance(value, OrderedDict): return self.new_section(key, **value) else: setattr(self, key, value) def items(self): return self.as_dict().items() def values(self): return self.as_dict().values() def pop(self, *args, **kwargs): return self.as_dict().pop(*args, **kwargs) def get(self, *args, **kwargs): return self.as_dict().get(*args, **kwargs) def update(self, config): self.as_dict().update(config.as_dict())
[docs] def as_dict(self): """ Returns all object attributes as a nested OrderedDict. Returns ------- dict Nested OrderedDict containing all object attributes. """ return self.__dict__["_attrs"]
def as_list(self): return list(self.as_dict().values())
[docs] def new_section(self, name, **configs): """ Creates a new Config object and add as an attribute of this instance. Parameters ---------- name: str Name of the new section. configs: Keyword arguments Parameters that will be stored in this section, accepts nested parameters. Examples -------- Simple use case:: config.new_section('new_section_name', attr1=value1, attr2=value2, ...) Nested parameters:: config.new_section('new_section_name', attr1=Config(attr1=value1, attr2=value2)) It's possible to access the variable like so:: config.new_section_name.attr1 """ self._nested_loader(name, Config(**configs))
[docs] def save(self, file_path): """ Saves current configuration to a JSON file. The configuration is stored as a nested dictionary (maintaining the order). Parameters ---------- file_path: str Path to write the file """ with open(file_path + ".yaml", "w") as f: yaml.dump(self, f, default_flow_style=False)
[docs] @classmethod def from_default(cls, name): """ Loads configuration from a default agent. Parameters ---------- name: str Name of the desired config file ('VanillaPG', add_more) Returns ------- Config A configuration object loaded from a JSON file """ if name == "PPO": return cls.load("CHANGE")
[docs] @staticmethod def load(file_path): """ Loads configuration from a JSON file. Parameters ---------- file_path: str Path of the file to be loaded. Returns ------- Config A configuration object loaded from a JSON file """ with open(file_path + ".yaml", "r") as f: return yaml.load(f)