Most data structures, especially in the learning module, perform serialization (to JSON) and deserialization (from JSON) using custom, adhoc logic for each data structure/class. A systematic way to handle ser/deser in general would be to make all data structures in autocat inherit from a base Serializable class that implements generic ser/deser functionality.
Example (basic) Serializable class:
class Serializable(object):
"""Base abstract class for a serializable object."""
def to_dict(self):
"""Convert and return object as dictionary."""
keys = {k.lstrip("_") for k in vars(self)}
attr = {k: Serializable._to_dict(self.__getattribute__(k)) for k in keys}
return attr
@staticmethod
def _to_dict(obj):
"""Convert obj to a dictionary, and return it."""
if isinstance(obj, list):
return [Serializable._to_dict(i) for i in obj]
elif hasattr(obj, "as_dict"):
return obj.as_dict()
else:
return obj
@classmethod
def from_dict(cls, ddict):
"""Construct an object from the input dictionary."""
return cls(**ddict)
and then autocat data structures need only to inherit from the Serializable class as follows:
class AutoCatDesignSpace(Serializable):
...
Most data structures, especially in the
learningmodule, perform serialization (to JSON) and deserialization (from JSON) using custom, adhoc logic for each data structure/class. A systematic way to handle ser/deser in general would be to make all data structures inautocatinherit from a baseSerializableclass that implements generic ser/deser functionality.Example (basic)
Serializableclass:and then
autocatdata structures need only to inherit from theSerializableclass as follows: