Come scaricare un dizionario Python per JSON quando le chiavi sono non banali oggetti?

import datetime, json
x = {'alpha': {datetime.date.today(): 'abcde'}}
print json.dumps(x)

Il codice sopra non riesce con un TypeError dato le chiavi di oggetti JSON devono essere stringhe. Il json.dumps funzione ha un parametro chiamato di default che viene chiamato quando il valore di un oggetto JSON solleva un TypeError, ma sembra che ci sia alcun modo per fare questo per il chiave. Che cosa è il modo più elegante per risolvere questo?

  • Sarebbe sufficiente a convertire il datetime oggetto in una stringa utilizzando strftime? O siete alla ricerca di un modo generico per oggetti complessi?
  • In questo caso, la conversione di tipo datetime.data di stringhe tramite il isoformat() il metodo funziona. Tuttavia, si deve lavorare sui tasti di un dizionario, così come per i valori.
InformationsquelleAutor ipartola | 2010-09-15

 

3 Replies
  1. 5

    È possibile estendere json.JSONEncoder per creare il tuo encoder, che sarà in grado di affrontare con data e ora.datetime oggetti (o oggetti di qualsiasi tipo di desiderio) in modo tale che una stringa è creato, che può essere riprodotto come un nuovo valore di tipo datetime.istanza di datetime. Credo che dovrebbe essere semplice come avere json.JSONEncoder chiamata repr() del datetime.datetime istanze.

    La procedura su come fare, così come descritto nel json modulo docs.

    Json modulo controlli il tipo di ogni valore deve codificare e per impostazione predefinita è solo sa come gestire dicts, liste, tuple, segnalazioni di operazioni sospette, unicode oggetti, int, long, float, booleani e di nessuno 🙂

    Anche importante per voi potrebbe essere il skipkeys argomento al JSONEncoder.


    Dopo aver letto i vostri commenti ho concluso che non c’è una soluzione facile per avere JSONEncoder codificare le chiavi di dizionari con una funzione personalizzata. Se siete interessati potete guardare l’origine e i metodi di iterencode() che chiama _iterencode() che chiama _iterencode_dict (), che è dove il tipo di errore viene generato.

    Più facile per voi sarebbe quella di creare un nuovo dict con isoformatted tasti come questo:

    import datetime, json
    
    D = {datetime.datetime.now(): 'foo',
         datetime.datetime.now(): 'bar'}
    
    new_D = {}
    
    for k,v in D.iteritems():
      new_D[k.isoformat()] = v
    
    json.dumps(new_D)

    Che restituisce ‘{“2010-09-15T23:24:36.169710”: “pippo”, “2010-09-15T23:24:36.169723”: “bar”}’. Per sottigliezze, avvolgetela con la funzione di 🙂

    • Che funziona solo per i valori di dizionario, non le chiavi. Sembra che ci sia alcun modo per ignorare la codifica delle chiavi.
    • Hai ragione, mi permetta di trovare la soluzione in origine (si può eventualmente eseguire l’override JSONEncoder.iterencode) in quanto non è chiaramente documentato.
    • Ok, ho controllato la fonte e non è possibile fare un JSONEncoder istanza di codificare dict tasti con una funzione personalizzata per un certo tipo facilmente. Si potrebbe essere meglio per creare un nuovo dict con le chiavi. Voglio aggiornare la mia risposta a riflettere su questo.
    • Grazie. Credo che non general purpose modo esiste. Credo che dovrebbe andare a vedere se a un certo punto questo può essere corretto in Python SDL come sembra una funzione utile.
    • Il motivo per cui questo viene fatto è perché non c’è “fail safe”, un modo per convertire un oggetto di qualsiasi tipo per la richiesta di tipo stringa per un json chiave. Si potrebbe chiamare repr() o str() su un oggetto che non è basestring ma queste non sono sempre implementato/utile e Pitoni motto è non fare le cose in modo implicito, che comprenderà fare questo.
    • Che senso. Ma avere la capacità di definire questo comportamento sarebbe bello. Esso dispone già di default() metodo che si può ignorare. Perché non fornire un default_key() metodo?

  2. 0

    si può fare
    x = {'alpha': {datetime.date.today().strftime('%d-%m-%Y'): 'abcde'}}

Lascia un commento