method - python class person
¿Cómo se crea una ID incremental en una clase de Python? (8)
¿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)
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í ...
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)
...
Conciso y elegante
import itertools
class resource_cl():
newid = itertools.count().next
def __init__(self):
self.id = resource_cl.newid()
...
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.
Me gusta usar generadores para ids. Permitir que el generador mantenga una lista de identificadores ya utilizados.
# [email protected]
# 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.
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 <enlace> sigue siendo válido pero la unicidad falla.
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
.