import json from typing import Any, Dict, List, Type, TypeVar T = TypeVar('T', bound='Serializable') class Serializable: @classmethod def from_dict(cls: Type[T], data: Dict[str, Any]) -> T: """Creates an instance of the class from a dictionary.""" instance = cls.__new__(cls) instance.deserialize_dict(data) return instance def serialize(self, file) -> str: """Serializes the object and all nested Serializable objects to JSON.""" def serialize_value(value: Any) -> Any: if isinstance(value, Serializable): return value.serialize_dict() elif isinstance(value, list): return [serialize_value(v) for v in value] elif isinstance(value, dict): return {k: serialize_value(v) for k, v in value.items()} else: return value attrs = {k: serialize_value(v) for k, v in self.__dict__.items() if not k.startswith('_')} return json.dumps(attrs, file, ensure_ascii=False, indent=2) def serialize_dict(self) -> Dict[str, Any]: """Serializes the object to a dictionary (for nested serialization).""" def serialize_value(value: Any) -> Any: if isinstance(value, Serializable): return value.serialize_dict() elif isinstance(value, list): return [serialize_value(v) for v in value] elif isinstance(value, dict): return {k: serialize_value(v) for k, v in value.items()} else: return value return {k: serialize_value(v) for k, v in self.__dict__.items() if not k.startswith('_')} def deserialize(self, json_str: str): """Deserializes JSON and recursively reconstructs Serializable objects.""" data = json.loads(json_str) self.deserialize_dict(data) def deserialize_dict(self, data: Dict[str, Any]): """Deserializes a dictionary and recursively reconstructs Serializable objects.""" for key, value in data.items(): if isinstance(value, dict) and 'py/class' in value: # Handle nested Serializable objects class_name = value['py/class'] class_ = globals()[class_name] setattr(self, key, class_.from_dict(value)) elif isinstance(value, list): # Handle lists of Serializable objects setattr(self, key, [ item if not isinstance(item, dict) or 'py/class' not in item else globals()[item['py/class']].from_dict(item) for item in value ]) else: setattr(self, key, value)