¿Cómo se crea una ID incremental en una clase de Python?

Me gustaría crear una ID única para cada objeto que creé, aquí está la clase:

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

Me gustaría tener un self.ID que se incremente automáticamente cada vez que creo una nueva referencia a la clase, como por ejemplo:

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

Sé que puedo hacer referencia a resource_cl, pero no estoy seguro de cómo proceder desde allí …

¿Es consciente de la función id en python y podría usarla en lugar de su idea de contador?

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

Conciso y elegante

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

Primero, use los nombres en mayúsculas para las clases. Nombres en minúsculas para atributos.

 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 

Usar la cuenta de itertools es genial para esto:

 >>> 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 

La misma interfaz funciona si más tarde necesita cambiar la forma en que se generan los valores, simplemente cambie la definición de id_generator .

Al intentar la respuesta más votada en Python 3, se encontrará con un error desde que se .next() .

En su lugar, podría hacer lo siguiente:

 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) ... 

Las identificaciones a veces se benefician al utilizar algunos campos del objeto al que desea hacer referencia. Esta es una técnica de base de datos de estilo antiguo.

por ejemplo, si tiene una aplicación que mantiene registros de las llamadas entrantes de los clientes, es posible que use una identificación generada por el tiempo = algo más

 ident = '%s:%.4s:%.9s' % ( time.time(), time.clock(), agent.name ) # don't forget to time.clock() once to initialize it 

solo beaware the time.time () y time.clock () son valores de retorno de computadora individuales a menos que se generen en el servidor. Y si está en el servidor, asegúrese de que el reloj de su servidor esté configurado correctamente; como siempre.

Otra nota sobre id () y repensar la respuesta de otros al respecto. id () puede devolver un número único, si y solo si recuerda cada id devuelto alguna vez, incluso si se elimina un objeto; lo que no hace (id ()). Asi que, por lo tanto…

En apoyo de lo que otros decían, id () no devuelve un número único; Es cierto que no puede garantizar un valor único si y solo si está almacenando esos valores de id () como referencias a objetos Y que está eliminando las instancias de los objetos para los que está obteniendo los id (). PERO ! usar id () como referencia significa que básicamente tiene un objeto que tiene una clave vinculada de alguna manera con otro objeto.

Esto no se invalida por la no unicidad de id (). Solo se invalida si no se comprueba si agregar un nuevo objeto tiene un id () preexistente ya almacenado como referencia a alguna otra instancia del objeto.

 storeit = {} object1 = object() print id(object1) 4357891223 storeit[ id(object1) ] = object1 object2 = object() print id(object2) 9834923411 storeit[ id(object2) ] = object2 storeit[ id(object1) ] = object() del object1 object3 = object() print id(object3) # after some 2 gigawatt tries magically i got 4357891223 # the same id as object1 had 

PERO storeit [4357891223] devuelve alguna otra instancia de objeto que no object3; por lo tanto, el sigue siendo válido pero la unicidad falla.

Me gusta usar generadores para ids. Permitir que el generador mantenga una lista de identificadores ya utilizados.

 # devplayer@gmail.com # 2012-07(jul)-19 class MakeUniqueStr(object): ''' unqstr = MakeUniqueStr(default_name='widget', sep='_') print(repr(unqstr('window'))) print(repr(unqstr('window'))) print(repr(unqstr('window'))) print(repr(unqstr('hello'))) print(repr(unqstr('hello'))) print(repr(unqstr('window'))) print(repr(unqstr('hello'))) 'window' 'window_00000' 'window_00001' 'hello' 'hello_00000' 'window_00002' 'hello_00001' ''' def __init__(self, default_name='default', sep='_'): self.default_name = default_name self.last_base_name = default_name self.sep = sep self.used_names = [] self.generator = self.Generator() self.generator.next() # initialize def __call__(self, name=None): if name <> None: self.last_base_name = name return self.generator.send(self.last_base_name) def _MakeName(self, name, index=1): '''_MakeName is called by the Generator. Generator will always have a name and an index to pass to _MakeName. Over ride this method to customize it.''' return name + self.sep + '%0.5d' % index def Generator(self): try_name = yield 'ready' # initialize index = 0 while 1: if try_name not in self.used_names: self.used_names.append( try_name ) sent_name = yield try_name try_name = sent_name continue try_name = self._MakeName( sent_name, index ) while try_name in self.used_names: index += 1 try_name = self._MakeName( sent_name, index ) index = 0 

Aunque esta no es una forma eficiente de memoria para grandes conjuntos de datos en memoria. Si desea usar algo así, modifíquelo para que el sistema operativo maneje el almacenamiento en caché de un archivo … digamos a través de una canalización con nombre.