Что называется этим назначением в Python? a = b = True
Я знаю о распаковке кортежей, но что это за назначение называется, где у вас есть несколько знаков равенства на одной строке? a la a = b = True
Он всегда меня немного подстраивает, особенно когда RHS изменен, но у меня возникают реальные проблемы с поиском правильных ключевых слов для поиска в документах.
Ответы
Ответ 1
Это цепочка заданий, а термин, используемый для описания, это...
- Могу ли я получить барабан, пожалуйста?
Назначение цепочки.
Я просто дал ему довольно google-прогон и обнаружил, что читать эту тему не так много, возможно, потому что большинство людей считают это очень прямолинейным (и только настоящие вундеркинды хотели бы узнать больше о тема).
В предыдущем выражении порядок оценки можно рассматривать как начинающийся с самого правого =
и затем работающий влево, что эквивалентно написанию:
b = True
a = b
Вышеуказанный порядок - это то, что большинство языков описывает цепочку назначений, но python делает это по-другому. В python выражение оценивается как эквивалентное ниже, хотя оно не приведет к каким-либо другим результатам, кроме того, что было описано ранее.
temporary_expr_result = True
a = temporary_expr_result
b = temporary_expr_result
Дополнительное чтение доступно здесь в stackoverflow:
Ответ 2
ОК, "прикованное назначение" было поисковым термином, которым я был, но после немного большего количества копания я думаю, что это не совсем правильно. но его легче искать, чем "особый случай оператора присваивания".
Статья в Википедии senderle связана с сообщением:
В Python операторы присваивания не являются выражениями и, следовательно, не верните значение. Вместо этого, цепочки назначений - это серия операторов с несколькими целями для одного выражения. присваивания выполняются слева направо, так что i = arr[i] = f()
оценивает выражение f()
, затем присваивает результат самому левому target, i
, а затем присваивает тот же результат следующей цели, arr[i]
, используя новое значение i
.
Другое сообщение в блоге:
В Python операторы присваивания не возвращают значение. Прикованный присваивание (или, точнее, код, который выглядит как привязанное присвоение заявления) признается и поддерживается как частный случай присваивание.
Это кажется мне самым правильным, при более близком чтении документов - в частности (target_list "=")+
- которые также говорят
Оператор присваивания вычисляет список выражений... и присваивает единственный результирующий объект для каждого из целевых списков, слева направо вправо.
Таким образом, это не действительно "оценивается с самого правого налево" - оценка RHS оценивается, а затем назначается с левой стороны цели вправо - не то, что я могу думать о каких-либо реальных (или даже надуманных) примерах, где это будет иметь значение.
Ответ 3
@refp answer дополнительно поддерживается этим выходом с помощью модуля dis
(дизассемблирования):
>>> def a(x):
... g = h = x
...
>>> import dis
>>> dis.dis(a)
2 0 LOAD_FAST 0 (x)
3 DUP_TOP
4 STORE_FAST 1 (g)
7 STORE_FAST 2 (h)
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
RHS извлекается и дублируется, а затем сохраняется в целевых переменных слева направо (попробуйте сами с помощью e = f = g = h = x
).
Некоторые другие плакаты были сбиты с толку, если RHS является вызовом функции, например a = b = fn()
- RHS оценивается только один раз, а затем результат присваивается каждой последовательной переменной. Это может привести к нежелательному совместному использованию, если возвращаемое значение является изменяемым, например, списком или dict.
Для тех, кто использует threading
, полезно отметить, что не существует "атомарности", подразумеваемой цепной формой присваивания по нескольким явным операторам присваивания - может существовать переключатель потоков между назначениями на g и h, а другой поток глядя на них, они могли видеть разные значения в двух переменных.
Из документации, 7.2. Заявления присваивания, g
и h
являются двумя целевыми списками, x
является списком выражений:
assignment_stmt ::= (target_list "=")+ (expression_list | yield_expression)
Оператор присваивания оценивает список выражений (помните, что это может быть одно выражение или список, разделенный запятыми, последний из которых имеет кортеж) и присваивает единственный результирующий объект каждому из целевых списков слева направо.
Ответ 4
получил укушенное python Chained Assignment сегодня, из-за моего невежества. в коде
if l1.val <= l2.val:
tail = tail.next = l1 # this line
l1 = l1.next
я ожидал, что
tail.next = l1
tail = tail.next
# or equivalently
# tail = l1
тогда как я получил ниже, которые производят цикл self в списке, оставьте меня в бесконечном цикле, кричит...
tail = l1
tail.next = l1 # now l1.next is changed to l1 itself
так как при a = b = c,
один путь (например, python), эквивалентный
tmp = evaluate(c)
evaluate(a) = tmp
evaluate(b) = tmp
и имеют равный правый операнд для двух присваиваний.
другой (например, С++), эквивалентный
evaluate(b) = evaluate(c)
evaluate(a) = evaluate(b)
так как в этом случае a = b = c
в основном
b = c
a = b
и два правых операнда могут быть разными.
Вот почему аналогичный код хорошо работает на С++.
Ответ 5
https://pmmodinews.com/congress-says-pm-modi-interview-was-just-i-me-myself/ Я ХОЧУ, ЧТОБЫ СЛЕДОВАТЬ ПРИБЫТЬ, ПОСЛЕ ТОГО, КАК МОДЫ ПРЕМЬЕР-МИНИСТРА ИНДИИ