From e2d6ee66ccd58ebfe0a188b2ea73cf7c961aa01c Mon Sep 17 00:00:00 2001 From: Vadim Nifadev <36514612+nifadyev@users.noreply.github.com> Date: Thu, 18 Apr 2024 14:45:13 +0300 Subject: [PATCH] Translate Be careful with chained operations example --- translations/README-ru.md | 49 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/translations/README-ru.md b/translations/README-ru.md index 3e7170b..92b9e82 100644 --- a/translations/README-ru.md +++ b/translations/README-ru.md @@ -275,7 +275,7 @@ False - После "интернирования" многие переменные могут ссылаться на один и тот же строковый объект в памяти (тем самым экономя память). - В приведенных выше фрагментах строки неявно интернированы. Решение о том, когда неявно интернировать строку, зависит от реализации. Правила для интернирования строк следующие: - Все строки длиной 0 или 1 символа интернируются. - - Строки интернируются во время компиляции (`'wtf'` будет интернирована, но `''.join(['w'', 't'', 'f'])` - нет) + - Строки интернируются во время компиляции (`'wtf'` будет интернирована, но `''.join(['w'', 't', 'f'])` - нет) - Строки, не состоящие из букв ASCII, цифр или знаков подчеркивания, не интернируются. В примере выше `'wtf!'` не интернируется из-за `!`. Реализацию этого правила в CPython можно найти [здесь](https://github.com/python/cpython/blob/3.6/Objects/codeobject.c#L19) ![image](/images/string-intern/string_intern.png) - Когда переменные `a` и `b` принимают значение `"wtf!"` в одной строке, интерпретатор Python создает новый объект, а затем одновременно ссылается на вторую переменную. Если это выполняется в отдельных строках, он не "знает", что уже существует `"wtf!"` как объект (потому что `"wtf!"` не является неявно интернированным в соответствии с фактами, упомянутыми выше). Это оптимизация во время компиляции, не применяется к версиям CPython 3.7.x (более подробное обсуждение смотрите здесь [issue](https://github.com/satwikkansal/wtfpython/issues/100)). @@ -284,3 +284,50 @@ False - Примечание: В Python 3.7 складывание констант было перенесено из оптимизатора peephole в новый оптимизатор AST с некоторыми изменениями в логике, поэтому четвертый фрагмент не работает в Python 3.7. Подробнее об изменении можно прочитать [здесь](https://bugs.python.org/issue11549). --- + + +### ▶ Осторожнее с цепочкой операций + +```py +>>> (False == False) in [False] # логично +False +>>> False == (False in [False]) # все еще логично +False +>>> False == False in [False] # а теперь что? + +True + +>>> True is False == False +False +>>> False is False is False +True + +>>> 1 > 0 < 1 +True +>>> (1 > 0) < 1 +False +>>> 1 > (0 < 1) +False +``` + +#### 💡 Объяснение: + +Согласно https://docs.python.org/3/reference/expressions.html#comparisons + +> Формально, если a, b, c, ..., y, z - выражения, а op1, op2, ..., opN - операторы сравнения, то a op1 b op2 c ... y opN z эквивалентно a op1 b и b op2 c и ... y opN z, за исключением того, что каждое выражение оценивается не более одного раза. + +Хотя такое поведение может показаться глупым в приведенных выше примерах, оно просто фантастично для таких вещей, как `a == b == c` и `0 <= x <= 100`. + +* `False is False is False` эквивалентно `(False is False) и (False is False)`. +* `True is False == False` эквивалентно `(True is False) and (False == False)` и так как первая часть высказывания (`True is False`) оценивается в `False`, то все выражение приводится к `False`. +* `1 > 0 < 1` эквивалентно `(1 > 0) и (0 < 1)`, которое приводится к `True`. +* Выражение `(1 > 0) < 1` эквивалентно `True < 1` и + ```py + >>> int(True) + 1 + >>> True + 1 # не относится к данному примеру, но просто для интереса + 2 + ``` + В итоге, `1 < 1` выполняется и дает результат `False` + +---