mirror of
https://github.com/satwikkansal/wtfpython
synced 2024-11-24 03:54:25 +01:00
Translate Bloating instance dict's example
This commit is contained in:
parent
4b4951d755
commit
9e2508ae6a
64
translations/README-ru.md
vendored
64
translations/README-ru.md
vendored
@ -3566,3 +3566,67 @@ KeyError: 1
|
|||||||
+ Этот процесс не обратим для конкретного экземпляра `dict`, и ключ даже не обязательно должен существовать в словаре. Поэтому попытка неудачного поиска имеет тот же эффект.
|
+ Этот процесс не обратим для конкретного экземпляра `dict`, и ключ даже не обязательно должен существовать в словаре. Поэтому попытка неудачного поиска имеет тот же эффект.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
### ▶ Раздуваем экземпляры словарей *
|
||||||
|
<!-- Example ID: fe706ab4-1615-c0ba-a078-76c98cbe3f48 --->
|
||||||
|
```py
|
||||||
|
import sys
|
||||||
|
|
||||||
|
class SomeClass:
|
||||||
|
def __init__(self):
|
||||||
|
self.some_attr1 = 1
|
||||||
|
self.some_attr2 = 2
|
||||||
|
self.some_attr3 = 3
|
||||||
|
self.some_attr4 = 4
|
||||||
|
|
||||||
|
|
||||||
|
def dict_size(o):
|
||||||
|
return sys.getsizeof(o.__dict__)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
**Результат:** (Python 3.8, другие версии Python 3 могут немного отличаться)
|
||||||
|
```py
|
||||||
|
>>> o1 = SomeClass()
|
||||||
|
>>> o2 = SomeClass()
|
||||||
|
>>> dict_size(o1)
|
||||||
|
104
|
||||||
|
>>> dict_size(o2)
|
||||||
|
104
|
||||||
|
>>> del o1.some_attr1
|
||||||
|
>>> o3 = SomeClass()
|
||||||
|
>>> dict_size(o3)
|
||||||
|
232
|
||||||
|
>>> dict_size(o1)
|
||||||
|
232
|
||||||
|
```
|
||||||
|
|
||||||
|
Попробуем снова... В новом сессии интерпретатора:
|
||||||
|
|
||||||
|
```py
|
||||||
|
>>> o1 = SomeClass()
|
||||||
|
>>> o2 = SomeClass()
|
||||||
|
>>> dict_size(o1)
|
||||||
|
104 # как ожидается
|
||||||
|
>>> o1.some_attr5 = 5
|
||||||
|
>>> o1.some_attr6 = 6
|
||||||
|
>>> dict_size(o1)
|
||||||
|
360
|
||||||
|
>>> dict_size(o2)
|
||||||
|
272
|
||||||
|
>>> o3 = SomeClass()
|
||||||
|
>>> dict_size(o3)
|
||||||
|
232
|
||||||
|
```
|
||||||
|
|
||||||
|
Что заставляет эти словари раздуваться? И почему только созданные объекты также раздуваются?
|
||||||
|
|
||||||
|
#### 💡 Объяснение:
|
||||||
|
+ CPython может повторно использовать один и тот же объект "keys" в нескольких словарях. Это было добавлено в [PEP 412](https://www.python.org/dev/peps/pep-0412/) с целью сокращения использования памяти, особенно в экземплярах словарей - где ключи (атрибуты экземпляра), как правило, общие для всех экземпляров.
|
||||||
|
+ Эта оптимизация совершенно беспроблемна для экземпляров словарей, но она не работает, если нарушены некоторые условия.
|
||||||
|
+ Словари с общим доступом к ключам не поддерживают удаление; если атрибут экземпляра удаляется, словарь становится "не общим", и общий доступ к ключам отключается для всех последующих экземпляров того же класса.
|
||||||
|
+ Кроме того, если размер ключей словаря был изменен (из-за вставки новых ключей), они остаются общими *только* если они используются только одним словарем (это позволяет добавить много атрибутов в `__init__` самого первого созданного экземпляра, не вызывая "unshare"). Если на момент изменения размера существует несколько экземпляров, совместное использование ключей отключается для всех последующих экземпляров одного класса: CPython не может определить, используют ли ваши экземпляры один и тот же набор атрибутов, и решает отказаться от попытки поделиться ключами.
|
||||||
|
+ Небольшой совет, если вы стремитесь уменьшить занимаемый программой объем памяти: не удаляйте атрибуты экземпляров и обязательно инициализируйте все атрибуты в `__init__`!
|
||||||
|
|
||||||
|
---
|
||||||
|
Loading…
Reference in New Issue
Block a user