Мова Python (особливо 3.x) дозволяє дуже загальне розпаковування ітерацій, простим прикладом яких є
a, *rest = 1, 2, 3
Протягом багатьох років це розпакування поступово узагальнювалось (див., Наприклад, PEP 3132 та PEP 448 ), дозволяючи використовувати його у все більшій кількості обставин. Тому я був здивований, виявивши, що наступне є неприпустимим синтаксисом у Python 3.6 (і залишається таким у Python 3.7):
def f():
rest = [2, 3]
return 1, *rest # Invalid
Я можу змусити це працювати, інкапсулюючи повернутий кортеж у дужки так:
def f():
rest = [2, 3]
return (1, *rest) # Valid
Той факт, що я використовую це у return
заяві, здається важливим, як
t = 1, *rest
насправді є законним і призводить до того ж, як з дужками, так і без них.
Чи цей випадок просто забутий розробниками Python, чи є якісь причини, чому цей випадок є недійсним синтаксисом?
Чому я дбаю
Це порушує важливий контракт, який, на мою думку, я мав з мовою Python. Розглянемо наступне (також дійсне) рішення:
def f():
rest = [2, 3]
t = 1, *rest
return t
Зазвичай, коли у мене є такий код, я вважаю t
тимчасове ім'я, від якого я мав би змогу позбутися, просто замінивши його t
в нижньому рядку його визначенням. Однак у цьому випадку це призводить до недійсного коду
def f():
rest = [2, 3]
return 1, *rest
Звичайно, немає особливої праці розміщувати дужки навколо поверненого значення, але зазвичай додаткові дужки потрібні лише для того, щоб розрізнити кілька можливих результатів (групування). Тут це не так, оскільки залишення дужок не спричиняє якоїсь іншої небажаної поведінки, а навпаки, взагалі ніякої поведінки.
Оновлення
Оскільки Python 3.8 (див. Пункт 7 у цьому списку ), узагальнений синтаксис, обговорений вище, тепер діє.