Reputation: 58662
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
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
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
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