From b1a8aadd704c13ecac3d771a6903afdaeee1d080 Mon Sep 17 00:00:00 2001 From: Vadim Nifadev <36514612+nifadyev@users.noreply.github.com> Date: Tue, 23 Apr 2024 08:53:40 +0300 Subject: [PATCH] Translate Stubborn operation example --- translations/README-ru.md | 47 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/translations/README-ru.md b/translations/README-ru.md index f880219..cdf5133 100644 --- a/translations/README-ru.md +++ b/translations/README-ru.md @@ -1990,3 +1990,50 @@ for i in x: * В Python 3.7.6 и выше при попытке запустить пример вызывается исключение `RuntimeError: dictionary keys changed during iteration`. --- + + +### ▶ Упрямая операция `del` + + + +```py +class SomeClass: + def __del__(self): + print("Deleted!") +``` + +**Результат:** +1\. +```py +>>> x = SomeClass() +>>> y = x +>>> del x # должно быть выведено "Deleted!" +>>> del y +Deleted! +``` + +Фух, наконец-то удалили. Вы, наверное, догадались, что спасло `__del__` от вызова в нашей первой попытке удалить `x`. Давайте добавим в пример еще больше изюминок. + +2\. +```py +>>> x = SomeClass() +>>> y = x +>>> del x +>>> y # проверяем, существует ли y +<__main__.SomeClass instance at 0x7f98a1a67fc8> +>>> del y # Как и в прошлом примере, вывод должен содержать "Deleted!" +>>> globals() # но вывод пуст. Проверим все глобальные переменные +Deleted! +{'__builtins__': , 'SomeClass': , '__package__': None, '__name__': '__main__', '__doc__': None} +``` + +Вот сейчас переменная `y` удалена :confused: + +#### 💡 Объяснение: + ++ `del x` не вызывает напрямую `x.__del__()`. ++ Когда встречается `del x`, Python удаляет имя `x` из текущей области видимости и уменьшает на 1 количество ссылок на объект, на который ссылается `x`. `__del__()` вызывается только тогда, когда счетчик ссылок объекта достигает нуля. ++ Во втором фрагменте вывода `__del__()` не была вызвана, потому что предыдущий оператор (`>>> y`) в интерактивном интерпретаторе создал еще одну ссылку на тот же объект (в частности, магическую переменную `_`, которая ссылается на значение результата последнего не `None` выражения в REPL), тем самым не позволив счетчику ссылок достичь нуля, когда было встречено `del y`. ++ Вызов `globals` (или вообще выполнение чего-либо, что будет иметь результат, отличный от `None`) заставил `_` сослаться на новый результат, отбросив существующую ссылку. Теперь количество ссылок достигло 0, и мы можем видеть, как выводится "Deleted!" (наконец-то!). + +---