Version 21 (modified by 4 years ago) ( diff ) | ,
---|
Pyson
Pyson converts between dicts/lists and python3 objects. It uses some annotations inspired by jackson.
install:
pip install https://tracinsy.ewi.tudelft.nl/pubtrac/Utilities/export/142/pyson/dist/pyson-1.0.0.tar.gz
or from your setup.py
install_requires=[ "pyson@pip install https://tracinsy.ewi.tudelft.nl/pubtrac/Utilities/export/142/pyson/dist/pyson-1.0.0.tar.gz"],
NOTICE you may want to use the latest version. Check packson3/dist for the latest.
The basic version determines the types for (de)serialization from the init function in the involved classes. Polymorphism is supported, so derived classes can (de)serialized from a superclass.
Basic Mechanism
The basic mechanism for pyson is to look at the init function of the class under serialization. The arguments in the init function are matched to the json fields. The arguments in the init must be fully typed, and these types are used to determine how to interpret the json content.
Examples
See pyson/test/ObjectMapperTest.py for many examples.
A simple example, deserializng a dict with objects
from pyson.ObjectMapper import ObjectMapper from pyson.JsonTypeInfo import JsonTypeInfo from pyson.JsonTypeInfo import Id,As from typing import Dict @JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT) class Simple: def __init__(self, a:int): self._a=a def geta(self)->int: return self._a def __eq__(self, other): return isinstance(other, self.__class__) and \ self._a==other._a def __str__(self): return self._name+","+str(self._a) pyson=ObjectMapper() objson = { 'a':{"Simple":{'a':1}},'c':{"Simple":{'a':3}}} obj=pyson.parse(objson, Dict[str,Simple]) obj['a'].geta()
A complex example showing many things at once
from pyson.ObjectMapper import ObjectMapper from pyson.JsonSubTypes import JsonSubTypes from pyson.JsonTypeInfo import JsonTypeInfo from pyson.JsonTypeInfo import Id,As from typing import Dict,List,Set import json class Props: ''' compound class with properties, used for testing ''' def __init__(self, age:int, name:str): if age<0: raise ValueError("age must be >0, got "+str(age)) self._age=age self._name=name; def __str__(self): return self._name+","+str(self._age) def getage(self): return self._age def getname(self): return self._name def __eq__(self, other): return isinstance(other, self.__class__) and \ self._name==other._name and self._age==other._age @JsonSubTypes(["__main__.Bear"]) @JsonTypeInfo(use=Id.NAME, include=As.WRAPPER_OBJECT) class Animal: pass class Bear(Animal): def __init__(self, props:Props): self._props=props def __str__(self): return "Bear["+str(self._props)+"]" def getprops(self): return self._props def __eq__(self, other): return isinstance(other, self.__class__) and \ self._props==other._props pyson=ObjectMapper() obj=Bear(Props(1,'bruno')) res=pyson.toJson(obj) print("result:"+str(res)) bson={'Bear': {'props': {'age': 1, 'name': 'bruno'}}} res=pyson.parse(bson, Animal) print("Deserialized an Animal! -->"+str(res))
NOTICE: our code allows you to use objects as keys, as python does allow this. However json requires strings as keys.
Add/Extend annotations at runtime
You can also add/extend existing annotations at runtime. You just need to update the class and function attributes. For now, check the source code for details.