Ответ 1
Вы знаете о id function в python и можете ли вы использовать его вместо идеи вашего счетчика?
class C(): pass
x = C()
y = C()
print(id(x), id(y)) #(4400352, 16982704)
Я хотел бы создать уникальный идентификатор для каждого созданного мной объекта - здесь класс:
class resource_cl :
def __init__(self, Name, Position, Type, Active):
self.Name = Name
self.Position = Position
self.Type = Type
self.Active = Active
Я хотел бы иметь self.ID, который автоматически увеличивается каждый раз, когда я создаю новую ссылку на класс, например:
resources = []
resources.append(resource_cl('Sam Sneed', 'Programmer', 'full time', True))
Я знаю, что могу ссылаться на ресурс_cl, но я не уверен, как исходить оттуда...
Вы знаете о id function в python и можете ли вы использовать его вместо идеи вашего счетчика?
class C(): pass
x = C()
y = C()
print(id(x), id(y)) #(4400352, 16982704)
Краткий и элегантный:
import itertools
class resource_cl():
newid = itertools.count().next
def __init__(self):
self.id = resource_cl.newid()
...
Сначала используйте имена верхнего уровня для классов. имена нижних регистров для атрибутов.
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
Использование count из itertools отлично подходит для этого:
>>> 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
Тот же интерфейс работает, если позже вам нужно изменить способ создания значений, вы просто измените определение id_generator
.
Идентификаторы иногда выигрывают от использования некоторых полей объекта, который вы хотели бы ссылаться. Это старый метод базы данных.
например, если у вас есть приложение, которое хранит записи для входящих звонков клиентов, тогда можно использовать идентификатор, созданный по времени = что-то еще
ident = '%s:%.4s:%.9s' % ( time.time(), time.clock(), agent.name )
# don't forget to time.clock() once to initialize it
только beaware time.time() и time.clock() являются индивидуальными значениями возврата компьютера, если только они не сгенерированы на сервере. И если на сервере убедитесь, что ваши серверные часы установлены правильно; как всегда.
Еще одна заметка о id() и пересмотр другого ответа об этом. id() может возвращать уникальный номер, если и только если он запоминает каждый возвращаемый идентификатор, даже если объект удален; который он (id()) не делает. Итак, поэтому...
В подтверждение того, что другие говорили, что id() не возвращает уникальный номер; Верно, что он не может гарантировать уникальное значение тогда и только тогда, когда вы храните эти значения id() в качестве ссылок на объекты AND, что вы удаляете экземпляры объектов, для которых вы получаете id() s. НО! использование id() в качестве ссылочного означает, что у вас в основном есть объект, у которого есть ключ, связанный каким-то образом с другим объектом.
Это не является недействительным по неединственности id(). Это недействительно, если вы не проверяете, имеет ли ранее добавленный новый объект уже существующий id() уже как ссылку на какой-либо другой экземпляр объекта.
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
BUT storeit [4357891223] возвращает другой экземпляр объекта, а не object3; поэтому <link> остается в силе, но уникальность терпит неудачу.
Мне нравится использовать генераторы для идентификаторов. Разрешите генератору поддерживать список уже используемых идентификаторов.
# [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
Хотя это не очень эффективный способ хранения огромных наборов данных в памяти. Если вы хотите использовать что-то вроде этого, измените это, чтобы кэшировать дескриптор ОС в файл... скажем через именованный канал.
При попытке получить самый высокий голос в Python 3 вы .next()
с ошибкой, так как .next()
был удален.
Вместо этого вы можете сделать следующее:
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)
...