2014-09-25 18 views
11

Scenario: si ha una tupla lunga come risultato di una query SQL e si desidera decomprimerlo in valori singoli. Qual è il modo migliore per farlo rispettando PEP8? Finora ho queste tre opzioni:Idiom per disimballaggio lungo tupla

  1. singola assegnazione, utilizzare backslash di dividere su più linee

    person_id, first_name, last_name, email, \ 
        birth_date, graduation_year, home_street, \ 
        home_city, home_zip, mail_street, mail_city, \ 
        mail_zip = row 
    
  2. singola assegnazione, gruppo lato sinistro in parantheses e rompere le linee senza una barra rovesciata

    (person_id, first_name, last_name, email, 
        birth_date, graduation_year, home_street, 
        home_city, home_zip, mail_street, mail_city, 
        mail_zip) = row 
    
  3. suddiviso in più assegnazioni, ciascun raccordo in una singola linea

    012.
    person_id, first_name, last_name, email = row[0:4] 
    birth_date, graduation_year, home_street = row[4:7] 
    home_city, home_zip, mail_street, mail_city = row[7:11] 
    mail_zip = row[11] 
    

Quale delle tre opzioni è la migliore? C'è qualcosa di meglio?

+3

Opinione basata. Non mi piace la soluzione con il backslash alla fine di una riga perché il codice si interromperà se si dispone di un carattere invisibile (ad esempio spazio) dopo di esso. Per me, la seconda versione è la strada da percorrere. – Matthias

+2

Hai considerato un singolo ['namedtuple'] (https://docs.python.org/2/library/collections.html#collections.namedtuple) invece di nomi separati? – jonrsharpe

+3

@Matthias Chiede "mentre si conforma a PEP-8", e PEP-8 è piuttosto esplicito su quale usare. – chepner

risposta

13

Anwering your questions "Quale delle tre opzioni è la migliore?"

pep8 stati:

Il modo preferito di linee lunghe è usando continuazione di riga implicita di Python all'interno parentesi tonde, quadre e graffe. Le linee lunghe possono essere suddivise su più righe avvolgendo le espressioni tra parentesi. Questi dovrebbero essere usati preferibilmente usando un backslash per la continuazione della linea.

Questo significa che il secondo è preferito rispetto al primo. Anche il terzo è conforme al pep8, anche se personalmente non lo raccomanderebbe.

+1

+1 Il terzo è molto meno efficiente e richiede molti più codici byte per eseguire lo stesso compito. – chepner

5

Per rispondere "C'è qualcosa di meglio", vorrei suggerire che un namedtuple permette di accedere alle singole voci di dati con il minimo sforzo:

>>> from collections import namedtuple 
>>> Person = namedtuple("Person", ['person_id', 'first_name', 'last_name', 
            'email', 'birth_date', 'graduation_year', 
            'home_street', 'home_city', 'home_zip', 
            'mail_street', 'mail_city', 'mail_zip']) 
>>> row = range(12) # dummy data 
>>> p = Person(*row) # unpack tuple into namedtuple 
>>> p 
Person(person_id=0, first_name=1, last_name=2, email=3, birth_date=4, graduation_year=5, home_street=6, home_city=7, home_zip=8, mail_street=9, mail_city=10, mail_zip=11) 
>>> p.birth_date 
4 

Questo significa che accedere attributi, piuttosto che separare i nomi , ma è più leggero rispetto alla costruzione di una classe, mantiene tutti i dati dalla query insieme e espone i valori attraverso nomi sensibili.

+0

Questo va bene finché si deve fare più volte per la stessa sequenza di attributi. Tuttavia, se sai che non disimballerai questa riga in più di un posto, probabilmente è troppo pesante (invece di un singolo o pochi compiti, devi importare una collezione, definire una tupla con nome ecc. Solo per un singolo disimballaggio). – koniiiik

+0

@koniiiik per i documenti, 'namedtuple's *" non richiede più memoria delle normali tuple "*. La definizione del contenitore ha la stessa lunghezza del tuo attuale spacchettamento, quindi stai aggiungendo solo due righe ("importa" e scompatta). Se sei certo che lo userai solo una volta, però, potresti avere ragione. – jonrsharpe

+1

Beh, per lo meno, si tratta di passi non del tutto banali che possono rendere meno ovvio cosa sta succedendo.Ma di nuovo, dipende dalla situazione esatta. – koniiiik