index all instances by id - a memory leak?

D

Dan Barbus

Hi all,

I'm a python beginner, and I have a problem with no solution I can
see:

I want to index all instances of an object by an internal id (not the
hash) and be able to retrieve them later.

I created a class-level dictionary (Item._itemById) where I add every
new instance. My problem is:

How do I delete the instances when the class is no longer in use?
( having it in a map makes it 'in use' all the time, so my
implementation results in a memory leak :( ).

Here's the code:

class Item():
"""This is the base class for all data items"""

_idBase = None
_count = 0
_itemsById = {}

def __init__(self, title = ''):
Item._count += 1
self.id = Item._generateId(self)
Item._itemsById[self.id] = self
self.title = title

def __del__(self):
Item._count -= 1
# Should I do something here to delete the instance?
# Will this ever be called if the instance is in a static
dictionary?

def _generateId(self):
"""Generates an unique id for the instance. The id will be
unique
for both the current run and all runs in general.

"""
if not Item._idBase:
Item._idBase = str(hash(self))
return Item._idBase + '-' + str(Item._count).zfill(6)

def getItemById(id):
return _itemsById[id]
 
D

Dan Barbus

    def getItemById(id):
        return _itemsById[id]

I just saw that this won't compile. Still, ignoring this, I thing the
purpose of the code is pretty clear.

Thanks for any feedback.
 
J

Jason Scheirer

    def getItemById(id):
        return _itemsById[id]

I just saw that this won't compile. Still, ignoring this, I thing the
purpose of the code is pretty clear.

Thanks for any feedback.

Check the weakref module, you can create a WeakValueDictionary which
will not increment the refcount of the value, and will return None
after it's been garbage collected.
 
M

Marc 'BlackJack' Rintsch

def __del__(self):
Item._count -= 1
# Should I do something here to delete the instance?
# Will this ever be called if the instance is in a static
dictionary?

Don't use the `__del__()` method. It is not reliable as there are almost
no guarantees when or if at all it will be called. But its sole
existence may be the cause that objects of that class can't be garbage
collected. Read the documentation of `__del__()` for details.

Ciao,
Marc 'BlackJack' Rintsch
 
R

Richard Levasseur

    def getItemById(id):
        return _itemsById[id]
I just saw that this won't compile. Still, ignoring this, I thing the
purpose of the code is pretty clear.
Thanks for any feedback.

Check the weakref module, you can create a WeakValueDictionary which
will not increment the refcount of the value, and will return None
after it's been garbage collected.

Another idea: have an AbstractFactory that keeps track of instances
created. When you done, delete the abstract factory, which will
delete the internal index. You'll have to figure out how to pass the
factory around, and when to delete it. Weakref sounds better, overall.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top