Comments on: Faire manger du datetime à JSON en Python http://sametmax.com/faire-manger-du-datetime-a-json-en-python/ Du code, du cul Fri, 06 Sep 2019 09:34:15 +0000 hourly 1 https://wordpress.org/?v=4.9.7 By: Will http://sametmax.com/faire-manger-du-datetime-a-json-en-python/#comment-190911 Mon, 20 Nov 2017 12:30:43 +0000 http://sametmax.com/?p=9731#comment-190911 Une autre solution que je trouve simple et lisible :

<

pre>from datetime import datetime

def json_encoder(o):

if isinstance(o, datetime):

return {“isoformat”: o.isoformat(), “class“: str(o.class)}

if isinstance(o, (CustomClass1, CustomClass2)):

dic = o.dict

dic[“class“] = str(o.class)

return dic

raise TypeError(“CustomClass or datetime expected.”)

   
def json_decoder(dic):
    if "__class__" in dic:
        if dic["__class__"] == str(CustomClass1):
            return CustomClass1(**dic)
        if dic["__class__"] == str(datetime):
            return datetime.strptime(dic["isoformat"], "%Y-%m-%dT%H:%M:%S")  # ajoutez ".%f" pour les ms
        raise TypeError("CustomClass or datetime expected.")

#main
with open("test.json", "w") as f:
        json.dump(myobject, f, default=json_encoder, indent=4)
with open("test.json", "r") as f:
    myobject = json.load(f, object_hook=json_decoder)
]]>
By: OlyGrim http://sametmax.com/faire-manger-du-datetime-a-json-en-python/#comment-177622 Wed, 06 Apr 2016 15:53:03 +0000 http://sametmax.com/?p=9731#comment-177622 Dans l’exemple, la désérialisation de la date ne renvoie pas un datetime. C’est toujours une chaîne de caractère.

J’ai pas trop compris pourquoi (peut-être en as-tu parlé dans le guide ultime et définitif sur la POO) mais apparemment la méthode decode n’utilise pas l’attribut object_pairs_hook de l’instance mais de la classe parente. Pour corriger le tir, j’ai fait ceci:

import json

class Decoder(json.JSONDecoder):
    def __init__(self, format, **kwargs):
        if not kwargs.get("object_pairs_hook", None):
            kwargs["object_pairs_hook"] = self.object_pairs_hook
        super().__init__(**kwargs)
        self.format = format


#main
donnees = {"date": datetime.now(), "valeur": 160}
donnees_dumps = JSONEncoder().encode(donnees)
donnees_loads = Decoder(format='%Y-%m-%d').decode(donnees_dumps)

Avec ça, le print(donnees_loads) renvoie bien undatetime.

Mais j’avoue ne pas comprendre pourquoi cet attribut n’est pas pris en compte, alors que si je redéfini l’attribut indent dans l’encodeur, lui est bien pris en compte.

Juste 2 petites remarques: Dans la méthode decode_on_match de ton JSONDecoder, tu n’as pas défini self.datetime_format. Et object_pairs_hook n’est pas à la base une méthode mais un attribut (qui attend un callable).

PS: Désolé pour le formatage de mon code. J’ai bien utilisé les balises pre mais dans le pré-visualiseur le code n’apparaît pas correctement.

]]>
By: Sam http://sametmax.com/faire-manger-du-datetime-a-json-en-python/#comment-20982 Mon, 10 Mar 2014 12:12:20 +0000 http://sametmax.com/?p=9731#comment-20982 Tous des points parfaitement valides. Effectivement, ce seraient de bonnes améliorations.

]]>
By: Mathieu http://sametmax.com/faire-manger-du-datetime-a-json-en-python/#comment-20981 Mon, 10 Mar 2014 09:59:25 +0000 http://sametmax.com/?p=9731#comment-20981 +1, mieux vaut s’en tenir à isoformat, surtout qu’avec la méthode actuelle on perdrait les timezone des datetime conscient, ce qui est grave.

]]>
By: floweb http://sametmax.com/faire-manger-du-datetime-a-json-en-python/#comment-20980 Mon, 10 Mar 2014 09:46:08 +0000 http://sametmax.com/?p=9731#comment-20980 Comme Badu, je préfère la méthode .isoformat(), il vaut mieux garder les standards… ISO 8601 (UTC format)

]]>
By: Badeu http://sametmax.com/faire-manger-du-datetime-a-json-en-python/#comment-20970 Sun, 09 Mar 2014 22:30:32 +0000 http://sametmax.com/?p=9731#comment-20970 isinstance ? Erf…

Pourquoi ne pas utiliser ça dans le sérialiseur plutôt ?

if hasattr(obj, 'isoformat'):
    return obj.isoformat()

Rapide, pas cher, standard … et ça se fait bien manger par toutes les libs de tous les langages. Et puis après, il suffit d’avoir le désérialiseur idoine.

]]>