Une note sur la façon d'encoder un objet d'une classe définie par vous-même en Python et comment le décoder à partir du format Json. Page référencée:
Prenez cette classe comme exemple.
import json
from datetime import date
class MyA:
def __init__(self, i=0, d=date.today()):
self.i = i #type int
self.d = d #type de date
Tout d'abord, nous devons penser au format de l'objet en tant que données Json. Il semble naturel que l'objet MyA soit un objet avec `` i '' et 'd'
comme clés. De plus, les données de type date peuvent être une chaîne de caractères, mais convertissons-les rapidement en entier à l'aide de la méthode toordinal. Ensuite, par exemple
a = MyA(i=100, d=date(year=2345, month=6, day=12))
Le a défini comme est converti en données Json {" i ": 100," d ": 856291}
. Cela peut être bien, mais cela peut être fastidieux car vous ne savez pas à quel type revenir lors du décodage. Par conséquent, le nom de la classe est stocké dans la clé _type '' et la valeur est stockée dans la clé
valeur ''. En conséquence, les données Json ressemblent à ceci:
{ "_type": "MyA",
"value": {"i": 100,
"d": { "_type": "date",
"value": 856291}}}
Les commandes dump et dumps de la bibliothèque json de Python acceptent un argument appelé cls. Vous pouvez spécifier votre propre encodeur ici. Puisque JSONEncoder est une classe couramment utilisée, créez votre propre encodeur sur cette base. Ce que vous devez vraiment faire est de redéfinir une méthode appelée default.
class MyEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, date):
return {'_type': 'date', 'value': o.toordinal()}
if isinstance(o, MyA):
return {'_type': 'MyA', 'value': o.__dict__}
return json.JSONEncoder.default(self, o)
Comme vous pouvez le voir, vous n'avez qu'à écrire ce que chaque classe regarde directement, et la bibliothèque fait le bon travail de récursivité. (Dans le cas d'un objet de classe MyA, ce qui est renvoyé est un dictionnaire et les données de type date peuvent y être définies.)
Il peut être exécuté comme suit.
a = MyA(100, date(year=2345, month=6, day=12))
js = json.dumps(a, cls=MyEncoder)
print(js)
Résultat de l'exécution:
{"_type": "MyA", "value": {"i": 100, "d": {"_type": "date", "value": 856291}}}
Cela crée également un décodeur basé sur une classe appelée JSONDecoder. Cette fois-ci, lorsque l'objet de la classe parent JSONDecoder est créé, écrivez-le pour que le décodage nécessaire soit effectué dans la fonction passée à la variable appelée object_hook. Cela ressemble à ceci:
class MyDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self, object_hook=self.object_hook,
*args, **kwargs)
def object_hook(self, o):
if '_type' not in o:
return o
type = o['_type']
if type == 'date':
return date.fromordinal(o['value'])
elif type == 'MyA':
return MyA(**o['value'])
En tant que o de object_hook, le résultat du décodage normal est passé. Dans l'exemple ci-dessus, un dictionnaire avec _type '' et
value '' comme clés viendra, vous pouvez donc écrire le code pour le recréer dans un objet de la classe appropriée. Encore une fois, vous n'avez pas à penser au traitement récursif.
Suite à l'exécution au moment de l'encodage:
b = json.loads(js, cls=MyDecoder)
print(b.i, b.d)
Résultat de l'exécution:
100 2345-06-12
Recommended Posts