2017-06-19 2 views
1

J'ai besoin d'un moyen efficace d'écrire des fichiers contenant des dictionnaires, y compris datetime, et ensuite être capable de les lire comme des dicts. Dicts comme ceux-ci:Comment écrire et lire des dictionnaires datetime

my_dict = {'1.0': [datetime.datetime(2000, 1, 1, 0, 0, 0, 000000, tzinfo=tzutc())], '2.0': [datetime.datetime(2000, 1, 1, 0, 0, 0, 000000, tzinfo=tzutc())]} 

Essayer de vider avec JSON:

with open("my_file.json", 'w+') as f: 
    json.dump(my_dict, f) 

TypeError: Object of type 'datetime' is not JSON serializable 

également essayé d'écrire l'ensemble dict en tant que chaîne, puis l'importer avec YAML, qui a presque fonctionné, mais a eu l'indexation foiré.

with open("my_file", 'w+') as f: 
    f.write(str(my_dict)) 

with open("my_file", 'r') as f: 
    s = f.read() 
    new_dict = yaml.load(s) 

print(new_dict['1.0'][0]) 

Output: datetime.datetime(2000 
Expected: 2000-01-01 00:00:00+00:00 

Répondre

2

Vous pouvez utiliser Pickle. Il est utilisé pour sérialiser et désérialiser une structure d'objet Python. Tout objet en python peut être décapé afin qu'il puisse être sauvegardé sur le disque. Ce que fait le cornichon, c'est qu'il «sérialise» l'objet avant de l'écrire dans un fichier. Le décapage est un moyen de convertir un objet python (liste, dict, etc.) en un flux de caractères. L'idée est que ce flux de caractères contient toutes les informations nécessaires pour reconstruire l'objet dans un autre script python. Source

Cela fonctionnerait:

>>> import pickle 
>>> file_Name = "testfile" 
>>> fileObject = open(file_Name,'wb') 
>>> my_dict = {'1.0': [datetime.datetime(2000, 1, 1, 0, 0, 0, 000000, tzinfo=tzutc())], '2.0': [datetime.datetime(2000, 
1, 1, 0, 0, 0, 000000, tzinfo=tzutc())]} 
>>> pickle.dump(my_dict, fileObject) 
>>> fileObject.close() 
>>> fileObject = open(file_Name,'r') 
>>> my_dict_loaded = pickle.load(fileObject) 
>>> my_dict_loaded 
{'1.0': [datetime.datetime(2000, 1, 1, 0, 0, 0, 000000, tzinfo=tzutc())], '2.0': [datetime.datetime(2000, 
1, 1, 0, 0, 0, 000000, tzinfo=tzutc())]} 
+0

J'ai aimé cette approche, était beaucoup plus rapide que je ne l'imaginais – Aminoff

0

Vous pouvez utiliser la méthode strftime:

my_dict = { 
    '1.0': [ 
       datetime.datetime(
        2000, 
        1, 
        1, 
        0, 
        0, 
        0, 
        000000, 
        tzinfo=tzutc() 
      ).strftime("%Y-%m-%d %H:%M:%S")], 
    '2.0': [ 
       datetime.datetime(
        2000, 
        1, 
        1, 
        0, 
        0, 
        0, 
        000000, 
        tzinfo=tzutc() 
      ).strftime("%Y-%m-%d %H:%M:%S") 
      ] 

}

1

Vous pourriez le sentir est la main lourde, mais la bonne façon en python est d'utiliser un encodeur personnalisé. Vous pouvez choisir la mise en forme (iso ici, mais je suggère d'utiliser datetime.date() dans votre exemple.

from datetime import date,datetime 
import json, re 

class DateTimeAwareEncoder(json.JSONEncoder): 
    def default(self, o): 
     if isinstance(o, datetime): 
      return o.isoformat() 

     return json.JSONEncoder.default(self, o) 

json.dumps(yourobj, cls=DateTimeAwareEncoder) 

Comment utiliser un décodeur personnalisé est beaucoup plus compliqué et le plus souvent mieux traitées en chargeant avec json.loads puis transformer les touches connues pour éviter le décodeur personnalisé

+0

Merci pour cela – Aminoff

+0

Vous, monsieur, sauvé ma journée. –