Подтвердить что ты не робот

Значение оператора присваивания

Всем известно, что в назначениях Python не возвращаются значения, предположительно, чтобы избежать присвоений в операторах if, когда обычно используется только сравнение:

>>> if a = b:
  File "<stdin>", line 1
    if a = b:
         ^
SyntaxError: invalid syntax

>>> if a == b:
...     pass
...

По той же причине можно было бы заподозрить, что несколько присваиваний в одном и том же операторе были также синтаксическими ошибками.

Фактически, a = (b = 2) не является допустимым выражением:

>>> a = (b = 2)
  File "<stdin>", line 1
    a = (b = 2)
           ^
SyntaxError: invalid syntax

Итак, мой вопрос: почему a = b = 2 работает в Python, поскольку он работает на других языках, где присваивания имеют значение, например C?

>>> a = b = c = 2
>>> a, b, c
(2, 2, 2)

Является ли это поведение документированным? Я не мог найти ничего об этом в документации для операторов присваивания: http://docs.python.org/reference/simple_stmts.html#assignment-statements

4b9b3361

Ответ 1

Это прямо там в синтаксисе:

assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)

Маленький + в конце (target_list "=")+ означает "один или несколько". Таким образом, строка a = b = c = 2 состоит не из трех операторов присваивания, а из одного оператора присваивания с тремя списками целей.

Каждый целевой список в свою очередь состоит только из одной цели (идентификатор в этом случае).

Это также в тексте (выделено мной):

Оператор присваивания [...] присваивает единственному результирующему объекту каждому из целевых списков слева направо.

Это может привести к интересным результатам:

>>> (a,b) = c = (1,2)
>>> (a, b, c)
(1, 2, (1, 2))

Ответ 2

Еще один прекрасный пример:

>>a,b,c  = b = 1,2,3
>>b
(1, 2, 3)

Ответ 3

a = b = c = 2
b = 3
print a,b,c
>>> 2 3 2