Skip to content Skip to sidebar Skip to footer

Assigning Ids To Instances Of A Class (pythonic)

I want to have each instance of some class have a unique integer identifier based on the order that I create them, starting with (say) 0. In Java, I could do this with a static cla

Solution 1:

The following approach would be relatively pythonic (for my subjective judgement of pythonic - explicit, yet concise):

classCounterExample(object):

    instances_created = 0def__init__(self):
        CounterExample.instances_created += 1def__del__(self):
        """ If you want to track the current number of instances
            you can add a hook in __del__. Otherwise use
            __init__ and just count up.
        """
        CounterExample.instances_created -= 1

If you are facing a large number of classes, which need that kind of attribute, you could also consider writing a metaclass for that.

An example of a metaclass: http://www.youtube.com/watch?v=E_kZDvwofHY#t=0h56m10s.

Solution 2:

the-myyn's answer is good -- I think the class object is a perfectly fine place to stash the counter. However, note that as written it's not thread-safe. So wrap it in a classmethod that uses a lock:

import threading

classCounterExample(object):

    _next_id = 0
    _id_lock = threading.RLock()

    @classmethoddef_new_id(cls):
        with cls._id_lock:
            new_id = cls._next_id
            cls._next_id += 1return new_id

    def__init__(self):
        self.id = self._new_id()

deftest():
    defmake_some(n=1000):
        for i inrange(n):
            c = CounterExample()
            print"Thread %s; %s has id %i" % (threading.current_thread(), c, c.id)

    for i inrange(10):
        newthread = threading.Thread(target=make_some)
        newthread.start()

test()

This runs 10 threads creating 1000 instances each. If you run it without the locking code, you're likely to end up with the last id lower than 9999, demonstrating the race condition.

Solution 3:

I guess a good question is when and how are they being created? If you're just creating a certain number of them at one point in time then use a range in a for loop.

classA:
    def__init__ (self, id):
        self.id = id
        //do other stuff

class_list = []
for i in xrange(10):
    class_list.append(A(i))

That would be one pythonic way. If your making them whenever you need them, then I think the only way is to keep an id static variable somewhere. Though I'm not sure how you're making them.

EDIT: Oh, also, when in doubt "import this" can always help you on to the right track for figuring out what is "pythonic" ;)

Post a Comment for "Assigning Ids To Instances Of A Class (pythonic)"