Translate Stubborn operation example

This commit is contained in:
Vadim Nifadev 2024-04-23 08:53:40 +03:00
parent eccd68a4bd
commit b1a8aadd70
1 changed files with 47 additions and 0 deletions

View File

@ -1990,3 +1990,50 @@ for i in x:
* В Python 3.7.6 и выше при попытке запустить пример вызывается исключение `RuntimeError: dictionary keys changed during iteration`.
---
### ▶ Упрямая операция `del`
<!-- Example ID: 777ed4fd-3a2d-466f-95e7-c4058e61d78e --->
<!-- read-only -->
```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__': <module '__builtin__' (built-in)>, 'SomeClass': <class __main__.SomeClass at 0x7f98a1a5f668>, '__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!" (наконец-то!).
---