Domanda

Ho un metodo mio codice Python che restituisce una tupla di una riga da una query SQL.Diciamo che ha tre campi:(jobId, etichetta, nome utente)

Per facilità di passare in giro tra le funzioni, sto passando tutta la tupla come una variabile chiamata 'lavoro'.Alla fine, però, voglio arrivare alla bit, e ho usato un codice come questo:(jobId, etichetta, nome utente (username) = lavoro

Ho capito, tuttavia, che questo è un incubo nella manutenzione, perché ora non posso aggiungere nuovi campi per il set di risultati senza rompere tutti il mio codice esistente.Come ho scritto questo?

Qui ci sono le mie due ipotesi:(jobId, etichetta, nome utente (username) = (di lavoro[0], lavoro[1], lavoro[2]) ...ma che non scala bene quando si hanno 15...20 campi

o per convertire i risultati della query SQL per un dizionario subito e passare in giro (non ho il controllo sul fatto che si inizia la vita come una tupla, che fissa per me)

È stato utile?

Soluzione

Direi che un dizionario è sicuramente il modo migliore per farlo.E ' facilmente estendibile, permette di dare ad ogni valore di una ragionevole nome, e Python ha un sacco di built-in linguaggio di funzionalità per l'utilizzo e la manipolazione di dizionari.Se avete bisogno di aggiungere più campi più tardi, tutto quello che devi modificare è il codice che converte la tupla di un dizionario e il codice che effettivamente fa uso dei nuovi valori.

Per esempio:

job={}
job['jobid'], job['label'], job['username']=<querycode>

Altri suggerimenti

@Staale

C'è un modo migliore:

job = dict(zip(keys, values))

Questa è una vecchia questione, ma...

Suggerirei un nome tupla in questa situazione: collezioni.namedtuple

Questa è la parte, in particolare, che ci si aspetterebbe di trovare utili:

La creazione di sottoclassi non è utile per l'aggiunta di nuovi campi memorizzati.Invece, è sufficiente creare un nuovo nome tupla tipo di _fields attributo.

Forse questo è eccessivo per il tuo caso, ma sarei tentato di creare un "Lavoro" di classe che prende la tupla come argomento del costruttore e ha rispettive proprietà su di esso.Vorrei quindi passare le istanze di questa classe invece.

Vorrei usare un dizionario.È possibile convertire la tupla di un dizionario in questo modo:

values = <querycode>
keys = ["jobid", "label", "username"]
job = dict([[keys[i], values [i]] for i in xrange(len(values ))])

Questo sarà il primo a creare una matrice [["jobid", val1], ["etichetta", val2], ["username", val3]] e di convertirla in un dizionario.Se il risultato fine del conteggio o modifiche, è solo bisogno di cambiare la lista delle chiavi per abbinare il nuovo risultato.

PS ancora fresca su Python me, quindi ci potrebbero essere modi migliori fuori a fare questo.

Una vecchia questione, ma dal momento che nessuno detto vorrei aggiungere questo da Python Cookbook:

Ricetta 81252:Utilizzando dtuple Flessibile del Risultato della Query di Access

Questa ricetta è specificamente progettato per trattare con i risultati del database, e la dtuple soluzione consente di accedere i risultati per nome O numero di indice.Questo evita di avere accesso a tutto ciò che dal sottoscritto che è molto difficile da mantenere, come si è notato nella tua domanda.

Con una tupla sarà sempre una seccatura per aggiungere o modificare i campi.Hai ragione che un dizionario sarà molto meglio.

Se si desidera qualcosa con un po ' più amichevole sintassi che si potrebbe desiderare di dare un'occhiata alle risposte questa domanda su un semplice 'struct-come' oggetto.In questo modo si può passare intorno ad un oggetto, diciamo job, e accedere ai suoi campi anche più facilmente di una tupla o dict:

job.jobId, job.username = jobId, username

Se si utilizza il MySQLdb pacchetto, è possibile impostare il cursore oggetti per tornare dicts invece di tuple.

import MySQLdb, MySQLdb.cursors
conn = MySQLdb.connect(..., cursorclass=MySQLdb.cursors.DictCursor)
cur = conn.cursor() # a DictCursor
cur2 = conn.cursor(cursorclass=MySQLdb.cursors.Cursor) # a "normal" tuple cursor

Che ne dici di questo:

class TypedTuple:
    def __init__(self, fieldlist, items):
       self.fieldlist = fieldlist
       self.items = items
    def __getattr__(self, field):
       return self.items[self.fieldlist.index(field)]

Si potrebbe fare:

j = TypedTuple(["jobid", "label", "username"], job)
print j.jobid

Dovrebbe essere facile da sostituire self.fieldlist.index(field) con una ricerca nel dizionario più tardi...basta modificare il __init__ metodo!Qualcosa di simile Staale fa.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top