Serialization
Most of the Serialization process uses Archives, which describe every recorded object before transforming them into a storable format.
The archive API serializes objects whose exact classes are known to the serialization registry. The standard Python container types and supported Perceval classes are registered when Perceval is imported. It is possible to add your own classes to the registry (see Registering new classes).
Serializing an object
Create an OutputArchive, then add an object with
serialize():
>>> import perceval as pcvl
>>> from perceval.serialization import OutputArchive, Serialization
>>>
>>> circuit = pcvl.Circuit(2) // pcvl.BS.H()
>>> output_archive = OutputArchive()
>>> Serialization.serialize(circuit, output_archive)
>>> serialized_circuit = output_archive.to_text()
The returned string contains the archive format version, its root objects, and the registered type tags needed to reconstruct the objects. Treat this representation as an opaque string: use the archive API instead of parsing or editing it directly.
Set compress=True to produce a compressed text representation:
>>> compressed_circuit = output_archive.to_text(compress=True)
Both representations can be passed to from_text().
Deserializing an object
Build an InputArchive from the stored text, then retrieve the object with
deserialize():
>>> from perceval.serialization import InputArchive
>>>
>>> input_archive = InputArchive.from_text(serialized_circuit)
>>> restored_circuit = Serialization.deserialize(input_archive)
>>> type(restored_circuit) is pcvl.Circuit
True
>>> restored_circuit.m
2
Note
The legacy perceval.serialization.deserialize() method is able to read from an archive string.
In that case, it returns the first serialized object.
Serializing several objects
An archive can contain more than one root object. Call Serialization.serialize once for each object, then call
Serialization.deserialize in the same order:
>>> state = pcvl.BasicState("|1,0>")
>>> output_archive = OutputArchive()
>>> Serialization.serialize(circuit, output_archive)
>>> Serialization.serialize(state, output_archive)
>>>
>>> input_archive = InputArchive.from_text(output_archive.to_text())
>>> restored_circuit = Serialization.deserialize(input_archive)
>>> restored_state = Serialization.deserialize(input_archive)
Deserializing consumes one root from the input archive.
len(input_archive) returns the number of roots that have not yet been consumed.
Object identity
Objects are memoized inside an archive. When the same mutable object appears several times in the serialized object graph, every occurrence points to the same restored instance:
>>> shared = [1, 2]
>>> value = [shared, shared]
>>> output_archive = OutputArchive()
>>> Serialization.serialize(value, output_archive)
>>> restored = Serialization.deserialize(InputArchive.from_text(output_archive.to_text()))
>>> restored[0] is restored[1]
True
This memoization also allows registered serializers to handle cyclic object graphs.
API reference
- class perceval.serialization.OutputArchive(raise_on_unregistred_class=True)
Archive used to serialize objects
- save_attr(obj, attributes)
Adds all the given attributes of obj to the archive.
- Parameters:
obj – The object that is currently being added to the archive
attributes (
list[str]) – A list of attributes of the object that will be added to the archive
- Return type:
tuple[ADescriptor,list[object]]- Returns:
A PartialRecord, i.e. a descriptor and a list of all new objects to add to the archive.
- to_json()
- Return type:
dict[str,Any]- Returns:
A dict representation of the archive, that can be converted to str using json.dumps
- to_text(compress=False)
- Parameters:
compress (
bool) – If True, the resulting string will be compressed- Return type:
str- Returns:
A string representing all the data stored in the archive
- class perceval.serialization.InputArchive(raise_on_unregistred_class=True)
Archive used to deserialize objects
- create(index)
- Parameters:
index (
int) – The index of the object to create in the archive- Return type:
object- Returns:
The object that was created in the archive
- classmethod from_json(json_obj)
- Parameters:
json_obj (
dict) – a dict representing an archive, typically obtained by using an OutputArchive.to_json() method.- Return type:
- Returns:
A new InputArchive containing the data that were stored in the archive.
- classmethod from_text(txt)
- Parameters:
txt (
str) – a string representing an archive, typically obtained by using an OutputArchive.to_txt() method.- Return type:
- Returns:
A new InputArchive containing the data that were stored in the archive.
- load_attr(obj, desc)
Creates and loads as attributes all the objects described in desc into obj. :type obj: :param obj: The object that will receive the attributes. :type desc:
list[tuple[str,int]] :param desc: A list of pairs (attribute_name, index)
- static Serialization.serialize(obj, ar)
Adds obj to the output archive, marking it as a root object
- static Serialization.deserialize(ar)
Deserializes the next root object in the input archive, and returns it
- Raises:
RuntimeError – if all the roots have been deserialized.