Идиома для распаковки длинного кортежа

Сценарий: у вас длинный кортеж в результате SQL-запроса и вы хотите распаковать его в отдельные значения. Какой лучший способ сделать это, когда он соответствует PEP8? Пока у меня есть три варианта:

  1. однократное назначение, используйте обратную косую черту для разделения на несколько строк

    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. одиночное задание, групповая левая сторона в скобках и строки прерывания без обратной косой черты

    (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. разбивается на несколько заданий, каждый из которых помещается в одну строку

    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]
    

Какой из трех вариантов является лучшим? есть что-нибудь получше?

Ответ 1

Отвечая на вопрос "Какой из трех вариантов лучше?"

pep8:

Предпочтительным способом обертывания длинных строк является использование продолжения строки под Python в круглых скобках, скобках и фигурных скобках. Длинные строки могут быть разбиты на несколько строк, обертывая выражения в круглых скобках. Они должны использоваться вместо использования обратной косой черты для продолжения строки.

Это означает, что второй предпочтительнее первого. Третий тоже хорошо соответствует pep8, хотя лично не рекомендовал бы его.

Ответ 2

Чтобы ответить "есть ли что-нибудь лучше", я бы предположил, что namedtuple позволяет вам получать доступ к отдельным элементам данных с минимальной суматохой:

>>> 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

Это означает, что вы обращаетесь к атрибутам, а не к отдельным именам, но легче, чем к созданию класса, сохраняете все данные из вашего запроса вместе и выставляете значения через разумные имена.