ответа-myyn это хорошо - я думаю, объект класса - это прекрасное место, чтобы спрятать счетчик. Тем не менее, обратите внимание, что, как написано, оно не является потокобезопасным. Так завернуть его в classmethod, который использует блокировку:
import threading
class CounterExample(object):
_next_id = 0
_id_lock = threading.RLock()
@classmethod
def _new_id(cls):
with cls._id_lock:
new_id = cls._next_id
cls._next_id += 1
return new_id
def __init__(self):
self.id = self._new_id()
def test():
def make_some(n=1000):
for i in range(n):
c = CounterExample()
print "Thread %s; %s has id %i" % (threading.current_thread(), c, c.id)
for i in range(10):
newthread = threading.Thread(target=make_some)
newthread.start()
test()
Это запускает 10 потоков, создающих 1000 экземпляров каждый. Если вы запустите его без кода блокировки, вы, скорее всего, получите последний идентификатор ниже 9999, демонстрируя состояние гонки.
Возможно, вы также захотите поместить 'self.identifier = CounterExample.instances_created' в тело' __init__', поскольку, похоже, mellort хочет иметь каждый объект с уникальным идентификатором. (Это, в свою очередь, означает, что вы не захотите уменьшать 'instance_created' во время удаления, поскольку это может привести к тому, что объекты будут инициализированы позже, имея неидентичные идентификаторы.) – JAB
Это работает отлично, пока вы не попытаетесь сделать это с помощью внутренний класс, после чего он терпит неудачу с «CounterExample не определено». Есть ли что-то еще, что вам нужно сделать, чтобы он работал с внутренним классом? – Zxaos