bsr
bsr

Reputation: 58662

Python - Global counter

I am recursively generating few objects, which need a contiguous, unique id. How can I guarantee (easiest) the synchronization in python 2.7.

iid = 1

def next_id():
    iid += 1
    return iid

def process():
    # .. do something
    id = next_id()

Upvotes: 4

Views: 17443

Answers (3)

glglgl
glglgl

Reputation: 91017

from itertools import count
iid = count()

print next(iid) # 0
print next(iid) # 1
print next(iid) # 2

etc., and

new_iid = count(10)
print next(new_iid) # 10
print next(new_iid) # 11
print next(new_iid) # 12

for starting at other values than 0.

count() is essentially a generator which infinitely yields values.

Upvotes: 19

Claudiu
Claudiu

Reputation: 229321

Use a mutex:

import threading
iid = 1
iid_lock = threading.Lock()

def next_id():
    global iid
    with iid_lock:
        result = iid
        iid += 1
    return result

You might like to hide the internals in a class:

class IdGenerator(object):
    def __init__(self):
        self.cur_id = 1
        self.lock = threading.Lock()
    def next_id(self):
        with self.lock:
            result = self.cur_id
            self.cur_id += 1
        return result

EDIT: Based on the comments, it seems like you're not using threads. This means you don't need the locking mechanism at all. What you initially wrote would be sufficient, though you need the global keyword to make the global variable mutable:

iid = 1
def next_id():
    global iid
    res = iid
    iid += 1
    return res

Upvotes: 12

jimifiki
jimifiki

Reputation: 5534

You were thinking to something of this kind:

 class Counter():
    def __init__(self):
        self.theCount = -1 
    def __call__(self):
        self.theCount += 1
        return self.theCount 

class BorgCounter():
    Borg = {'theCount':-1} 
    def __init__(self):
        self.__dict__ = BorgCounter.Borg 
    def __call__(self):
        self.theCount += 1
        return self.theCount 

myCount = Counter() 
mycount2 = Counter() 
assert(myCount()==0)
assert(mycount2()==0)
assert(mycount2()==1)
assert(myCount()==1)
assert(myCount()==2)

myCount = BorgCounter() 
mycount2 = BorgCounter() 
assert(myCount()==0)
assert(mycount2()==1)
assert(mycount2()==2)
assert(myCount()==3)
assert(myCount()==4)

Upvotes: 0

Related Questions