Значение оператора присваивания
Всем известно, что в назначениях 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
Ответы
Ответ 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