Inherit from Serializable when you already have a normal constructor. Store
an attribute for each positional constructor argument, or implement to_dict()
with keys that the constructor accepts. Keyword-only arguments (after *) are
left out of the default to_dict(), so they can hold constructor options which
aren't part of the saved state.
from serializable import Serializable
class Sample(Serializable):
def __init__(self, name, count):
self.name = name
self.count = count
sample = Sample("tumor", 3)
restored = Sample.from_json(sample.to_json())
print(restored.name, restored.count)tumor 3
The base class supplies equality and a representation from the stored fields. For dataclasses, use the dataclass mixin to retain the methods generated by the dataclass decorator.
Continuing the preceding example, use the constructor-based class's file helpers. This example uses a temporary directory so it does not overwrite an existing file.
from pathlib import Path
from tempfile import TemporaryDirectory
with TemporaryDirectory() as directory:
path = Path(directory) / "sample.json"
sample.write_json_file(path)
restored = Sample.read_json_file(path)
print(restored == sample)True
DataclassSerializable provides JSON string methods, without the file helpers.
For a dataclass, write object.to_json() with Path.write_text() and reload
the text with YourClass.from_json().
Pickling uses the same to_dict() and from_dict() methods as JSON, so
renamed fields are handled the same way. Pickles written by
versions before 1.2.0 can still be loaded.
import pickle
restored = pickle.loads(pickle.dumps(sample))
print(restored == sample)True
Module-level helpers serialize supported containers as well as individual
objects. Continuing with sample from above:
from serializable import from_json, to_json
restored = from_json(to_json({"samples": [sample]}))
print(restored["samples"][0].name)tumor
Keep each object's class importable when loading it in another process. A notebook or a script's local class is a convenient demonstration; a class in an importable module is preferable for persisted data shared across programs.