Closed redeboer closed 3 years ago
Moved to issue description
With the switch to sympy and pickle this issue would also disappear right?
I would say so yes. Although it's unfortunate that we have no way to write the amplitude model to disk, other than pickling.
Generating the allowed transitions takes most time though. So we may have to open an issue for reading and writing StateTransitionGraph
s (see also #458).
Or are there other things that need to be serializable separately? Because it's not exactly clear from the title and that comment alone
I made https://github.com/ComPWA/expertsystem/issues/384#issuecomment-734913355 into the issue description. That issue description would indeed become irrelevant once SymPy has been implemented.
The original idea was to use a function (not a method) like
attr.asdict
(withrecurse=True
) to recursively serialize any data structure into adict
. Data structures that are not constructed through anattr.s
constructor, can be serialized by defining a 'serializer', see https://www.attrs.org/en/stable/examples.html#converting-to-collections-types.There are two big problems with this implementation:
We also want to construct the original data structures back from any
dict
that was created through thisasdict
function. IfAttrObject
is some class that is constructed with anattr.s
decorator, this can be done as follows:However, this only works if
AttrObject
is not a nested data structure.Classes such as
ParticleCollection
,Spin
, andParity
are not created throughattr.s
. We would have to provide some serializer for them, but this still doesn't really address #383, as we would have to put that serializer under some submodule other than. See here for the syntax that would be required.Conclusion: it would be better to define some
Protocol
orABC
that definesfromdict
andasdict
methods for any class that we want to be serializable, _including classes that were decorated withattr.s
.Some snippets of the function implementation
```python # expertsystem 0.6.4 from typing import Any, Callable, Optional import attr import expertsystem as es from expertsystem.particle import Parity, ParticleCollection, Spin Serializer = Callable[[type, attr.Attribute, Any], Any] """https://www.attrs.org/en/stable/extending.html#customize-value-serialization-in-asdict""" def asdict( instance: object, serializer: Optional[Serializer] = None, ) -> dict: if serializer is None: if not attr.has(type(instance)): serializer = value_serializer if not attr.has(type(instance)): return value_serializer("", "", instance) return attr.asdict(instance, recurse=True, value_serializer=serializer) def value_serializer(_: type, __: attr.Attribute, value: Any) -> Any: if isinstance(value, ParticleCollection): return { "particles": [ attr.asdict(p, value_serializer=value_serializer) for p in value ] } if isinstance(value, Parity): return {"value": int(value)} if isinstance(value, Spin): return { "magnitude": value.magnitude, "projection": value.projection, } return value pdg = es.io.load_pdg() definition = asdict(pdg) pdg_new = ParticleCollection(**definition) # <-- FAIL because nested assert pdg == pdg_new ```