How do you create an incremental ID in a Python Class

Viewed 71337

I would like to create a unique ID for each object I created - here's the class:

class resource_cl :
    def __init__(self, Name, Position, Type, Active):
        self.Name = Name
        self.Position = Position
        self.Type = Type
        self.Active = Active

I would like to have a self.ID that auto increments everytime I create a new reference to the class, such as:

resources = []
resources.append(resource_cl('Sam Sneed', 'Programmer', 'full time', True))

I know I can reference resource_cl, but I'm not sure how to proceed from there...

11 Answers

Concise and elegant:

import itertools

class resource_cl():
    newid = itertools.count().next
    def __init__(self):
        self.id = resource_cl.newid()
        ...

Trying the highest voted answer in python 3 you'll run into an error since .next() has been removed.

Instead you could do the following:

import itertools

class BarFoo:

    id_iter = itertools.count()

    def __init__(self):
        # Either:
        self.id = next(BarFoo.id_iter)

        # Or
        self.id = next(self.id_iter)
        ...

First, use Uppercase Names for Classes. lowercase names for attributes.

class Resource( object ):
    class_counter= 0
    def __init__(self, name, position, type, active):
        self.name = name
        self.position = position
        self.type = type
        self.active = active
        self.id= Resource.class_counter
        Resource.class_counter += 1

Using count from itertools is great for this:

>>> import itertools
>>> counter = itertools.count()
>>> a = next(counter)
>>> print a
0
>>> print next(counter)
1
>>> print next(counter)
2
>>> class A(object):
...   id_generator = itertools.count(100) # first generated is 100
...   def __init__(self):
...     self.id = next(self.id_generator)
>>> objs = [A(), A()]
>>> print objs[0].id, objs[1].id
100 101
>>> print next(counter) # each instance is independent
3

The same interface works if you later need to change how the values are generated, you just change the definition of id_generator.

Are you aware of the id function in python, and could you use it instead of your counter idea?

class C(): pass

x = C()
y = C()
print(id(x), id(y))    #(4400352, 16982704)

You could attach the count to the class as a class parameter, and then on init you're able to copy this value to an instance parameter.

This makes count a class param, and id an instance param. This works because integers are immutable in python, therefore the current value is copied and not the attribute itself.

class Counter:
    count = 0

    @classmethod
    def incr(self):
        self.count += 1
        return self.count

    def __init__(self):
        self.id = self.incr()

assert [Counter().id for _ in range(3)] == [1, 2, 3]
def create_next_id(cnt=0):
    def create_next_id_inner():
        nonlocal cnt
        cnt += 1
        return cnt - 1
    return create_next_id_inner
...
next_id = create_next_id()
...
my_data = {'id': next_id(), ...}
my_data2 = {'id': next_id(), ...}
...

Hello this may be the Lengthy way, But Worked very Fluently for me. Hope it Helps. I have done it using a External Text file named id.txt.

Just create an empty file named as above. Then run this snippet. That will definitely work.

def id_generator():
with open("id.txt", "r") as f:
    f.seek(0)
    fc = f.read(1)
    if not fc:
        with open("id.txt", "w") as f1:
            f1.write("1")
        id = 1
    else:
        f.seek(0)
        fc = f.read(1)
        nv = int(fc) + 1
        with open("id.txt", "w") as f2:
            f2.write(str(nv))
        id = nv

return id

And to get the Value from this Snippet do this.

id = id_generator()

If any of the Reader find it useful, Please pass a Comment and Let me know if my work Paid off.

Hope it helps. Thank You......

Related