Struttura dati complessa in python: basta dettare, ecc. o alcune classi?

3

Considera un'API del servizio web che restituisce un oggetto Json complesso. Usando gli strumenti Python di serie per il lavoro, questo leggerà dal servizio web come un dict che contiene, a sua volta, una combinazione di matrici, dit, stringhe e numeri.

Confesso: questi dati nascono in Java. In Java, esiste un modello di dati per questi dati. La mia domanda è: i programmatori Python tinti di lana desidererebbero un modello di dati di classe Python che aggiungesse un certo grado di notabilità, o si aspetterebbero di ricevere la situazione descritta nel primo paragrafo.

In termini di codice, qual è il valore di:

 text.tokens[3].part_of_speech

al contrario di:

 text['tokens'][3]['part_of_speech']

Sulla base di alcuni commenti, voglio espanderlo un po '. Quello che ho scritto sopra è tutto sul consumo di una struttura dati complessa che arriva in Python come Json, e posso vedere che 'zuccherarlo' con una pila di classi con i marcatori @property non è molto utile.

Un altro lato della moneta sta assemblando uno di questi. Come, certamente, una persona che ha speso molto più tempo in Java, C ++, C (e Lisp?) Che in Python, io tenderei a vedere il valore in alcune API che mi aiuta a ricordare i nomi di tutti i bit e pezzi. Quindi forse questo suggerisce semplicemente di fornire delle costanti che forniscono le chiavi definite?

    
posta bmargulies 14.05.2015 - 23:08
fonte

2 risposte

3

Non so che ci sia una risposta alla quale tutti sarebbero d'accordo, ma personalmente userò solo le classi Python integrate. Leggere i dizionari e le liste di JSON in Python è una cosa molto standard da fare, si mappa molto bene.

Sono tutto e per la programmazione OO, ma non vedo il punto nello scrivere una piccola classe per essere un sottile involucro rispetto ai potenti tipi di dati esistenti. Quando qualcuno legge il tuo codice, è solo un altro tipo da ingannare. Mentre le strutture dati standard sono, beh, standard. Sanno che è un ditt, se un programmatore vuole capire i contenuti a un certo punto, può semplicemente piazzare un breakpoint, stamparlo e lasciare che il programma continui a funzionare.

Inoltre, python ha una sintassi molto bella come dict e list comprehensions. Probabilmente stai perdendo tanta simpatia quanto guadagni non dovendo digitare alcuni extra [].

Rappresentare JSON in C ++ o Java è una situazione diversa, perché se la struttura JSON non è nota al momento della compilazione, quindi i tipi non sono noti in anticipo. Quindi scrivere una struttura dati personalizzata è comunque abbastanza necessario. Molto diverso in python.

    
risposta data 15.05.2015 - 00:59
fonte
1

Utilizzerei elenchi predefiniti per qualsiasi elenco (sequenze uniformi di oggetti a lunghezza variabile).

Utilizzerei le namedtuple per le classi per memorizzare i dati con insiemi fissi noti di campi denominati. È come oggetti, ma immutabili.

Quindi avresti il tuo text.tokens[3].part_of_speech == NOUN , ma non avrai text.tokens[3].part_of_speech = NOUN . L'immutabilità è spesso utile a prevenire un'intera classe di errori, però.

per es.

from collection import namedtuple

Token = namedtuple('Token', ['part_of_speech', 'whatnot'])
Text = namedtuple('Text', ['tokens', 'metainfo', 'stats'])

# ...

json_doc = json.load(...)
tokens = []
for json_token in json_doc['tokens']:
  t = Token(json_token['part_of_speech'], json_token['whatnot'])
  # or even t = Token(**json_token)
  tokens.append(t)
...
return Text(tokens, ...)
    
risposta data 15.05.2015 - 21:18
fonte

Leggi altre domande sui tag