Вопрос по python, dictionary, memory – Удаляет ли словарь метод clear () все связанные с предметом объекты из памяти?

23

Если словарь содержит изменяемые объекты или объекты пользовательских классов (например, набор запросов или даже DateTime), то вызовclear() в словаре удалить эти объекты из памяти? Ведет ли он себя иначе, чем перебирает диктовку иdelеть их?

например. рассматривать

<code>class MyClass(object):
    '''Test Class.'''

my_obj_1 = MyClass()
my_obj_2 = MyClass()

my_dict = { 'foo' : my_obj_1, 'bar' : my_obj_2 }
</code>

тогда это

<code>my_dict.clear()
</code>

такой же как

<code>for key in my_dict.keys():
    del my_dict[key]
</code>

?

Ваш Ответ

6   ответов
5

deleting them?

Стоит отметить, что любой пользовательский класс, реализующийMutableMapping абстрактный базовый класс получаетclear() как "бесплатный" смешанный метод.

Единственные методы, которые вам нужно переопределить, чтобы создать экземплярMutableMapping Подклассом являются:

__getitem__, __setitem__, __delitem__, __iter__, __len__

Поскольку вы можете хранить данные в своем классе отображения любым способом, единственный способclear() можно выяснить, как на самом деле очистить ваши данные с помощью одного или нескольких из этих пяти методов. Теперь вы можете догадаться, какие методыclear() использует, но зачем догадываться, когда мы можем экспериментировать?

import collections

class MyMap(collections.MutableMapping):
    def __init__(self, mydict):
        self._top_secret_data = mydict

    def __getitem__(self, key):
        print 'getitem'
        return self._top_secret_data[key]

    def __setitem__(self, key, value):
        raise Exception('where did you want that?')

    def __len__(self):
        raise Exception('a gentleman never tells')

    def __delitem__(self, key):
        print '[shredding intensifies]'
        del self._top_secret_data[key]

    def __iter__(self):
        def keygen():
            for key in self._top_secret_data:
                print 'faster! faster!'
                yield key
        return iter(keygen())

Используя класс, определенный выше, легко увидеть, какclear() реализовано:

>>> m = MyMap({1:'a', 2:'b', 3:'c'})
>>> m.clear()
faster! faster!
getitem
[shredding intensifies]
faster! faster!
getitem
[shredding intensifies]
faster! faster!
getitem
[shredding intensifies]
>>> 

Другими словами,clear() Метод Mixin в основном реализован какfor key in self: del self[key].

Теперь отказ от ответственности: встроенные типы, такие какdict реализованы в C, поэтомуdict.clear метод не может быть буквально идентичнымfor key in mydict: del mydict[key], Я ожидаю некоторой оптимизации за кулисами, возможно, совершенно другой стратегии - но, надеюсь, этот пример дает вам некоторое представление о том, как вы могли быexpect clear() метод для работы в Python.

1

команда clear очищает все пары значений ключа за один раз, чтобы функциональность была одинаковой, они как разыменовывают, так и оставляют задачу удаления ее из памяти выполняет сборщик мусора

3

del d['foo'] - он просто удаляет записи, но не влияет на сами ключи или значения.

Конечно, они могут стать предметом сбора мусора, если на них нет других ссылок.

@pepr Это правильно.
Да, поэтому ключ, который я пропустил здесь, это операция удаления, удаляет только ссылку, очистка памяти обрабатывается сборщиком мусора. 0xc0de
Другими словами, если или ключи или значения являются общими (назначенными другой переменной), их объекты не будут удалены ниd.clear()ни поdel d[key], В словаре хранятся ссылки на ключи и значения.references are deleted по операциям.
42

Python документация по диктам говорится, чтоdel d[key] удаляетd[key] из словаря покаd.clear() удаляет все ключи, поэтому в основном их поведение одинаково.

Что касается проблемы с памятью, в Python, когда вы "удаляете" вы в основном удаляете ссылку на объект. Когда на объект не ссылаются ни переменная, ни другой объект или он становится недоступным, он становитсяgarbage и может быть удален из памяти. Python имеет сборщик мусора, которыйfrom time to time он проверяет, какие объекты являются мусором, и освобождает память, выделенную для них. Если на объект, который вы удаляете из словаря, ссылается другая переменная, тогда он все еще доступен, поэтому он не является мусором, поэтому он не будет удален. Я оставляю здесь несколько ссылок, если вы заинтересованы в чтении о сборке мусора в целом и сборке мусора в python в частности.

http://en.wikipedia.org/wiki/Garbage_collection_(computer_science) http://www.digi.com/wiki/developer/index.php/Python_Garbage_Collection http://www.doughellmann.com/PyMOTW/gc/ http://docs.python.org/library/gc.html
1

MyClass объекты являются общими. Они по-прежнему будут доступны черезmy_obj_1 а такжеmy_obj_2.

5

clear() освободит память о хэш-наборе, используемом в dict, а извлекать ключ не будет.

a = dict.fromkeys(range(1000))

In [10]: sys.getsizeof(a)
Out[10]: 49432

In [11]: a.clear()

In [12]: sys.getsizeof(a)
Out[12]: 280

In [13]: a = dict.fromkeys(range(1000))

In [14]: for i in range(1000):
   ....:     del a[i]
   ....:     

In [15]: sys.getsizeof(a)
Out[15]: 49432
да! Я нашел то же самое, и это очень важно, когда ты имеешь дело с действительно большим диктатом. Я никогда не буду использоватьfor цикл, чтобы удалить все ключи, так как он просто не освобождает память и, следовательно, не имеет смысла

Похожие вопросы