如何在Python类中创建增量ID

时间:2021-01-20 23:22:48

I would like to create a unique ID for each object I created - here's the class:

我想为我创建的每个对象创建一个唯一的ID - 这是类:

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

I would like to have a self.ID that auto increments everytime I create a new reference to the class, such as:

我希望有一个self.ID,每次我创建一个新的类引用时自动递增,例如:

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

I know I can reference resource_cl, but I'm not sure how to proceed from there...

我知道我可以参考resource_cl,但我不确定如何从那里继续...

7 个解决方案

#1


5  

Are you aware of the id function in python, and could you use it instead of your counter idea?

你是否知道python中的id函数,你可以使用它而不是你的反思吗?

class C(): pass

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

#2


41  

Concise and elegant:

简洁优雅:

import itertools

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

#3


14  

First, use Uppercase Names for Classes. lowercase names for attributes.

首先,使用类的大写名称。属性的小写名称。

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

#4


11  

Using count from itertools is great for this:

使用来自itertools的count非常适合:

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

The same interface works if you later need to change how the values are generated, you just change the definition of id_generator.

如果稍后需要更改值的生成方式,则只需更改id_generator的定义即可使用相同的界面。

#5


1  

Ids sometimes benefit from using some fields of the object you wanted to reference. This is a old style database technique.

Ids有时会受益于使用您想要引用的对象的某些字段。这是一种旧式数据库技术。

for example if you have a app that keeps records for incoming customer phone calls, then possible use an id generated by time = some thing else

例如,如果您有一个应用程序来保留传入的客户电话呼叫的记录,那么可能使用由time =其他东西生成的id

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

only beaware the time.time() and time.clock() are individual computer return value unless on generated on the server. And if on the server make sure your server clock is set right; as always.

只知道time.time()和time.clock()是单独的计算机返回值,除非在服务器上生成。如果在服务器上确保您的服务器时钟设置正确;一如既往。

#6


0  

Another note on id() and rethinking other's answer about it. id() may return a unique number, if and only if it remembers every id ever returned even if an object is deleted; which it (id()) does not do. So therefore...

关于id()的另一个注释,并重新考虑其他人的答案。 id()可能会返回一个唯一的数字,当且仅当它记住所有返回的id,即使删除了一个对象;它(id())不做。因此......

In support of what others were saying that id() does not return a unique number; It is true that it can not guarentee a unique value if and only if you are storing those id() values as references to objects AND that you are deleting the instances of objects you are getting id()s for. BUT ! using id() as a reference means that you basically have an object that has a key linked somehow with another object.

支持其他人说id()不返回唯一的数字;确实,当且仅当您将这些id()值存储为对象的引用并且您正在删除您正在获取id()的对象的实例时,它才能保证唯一值。但是!使用id()作为引用意味着您基本上有一个对象,该对象具有以某种方式与另一个对象链接的键。

This is not invalidated by non-uniqueness of id(). It is only invalidated if you do not check if adding a new object has a preexisting id() already stored as a reference to some other instance of the object.

这不会因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 ] returns some other object instance not object3; therefore the < link > remains valid but the uniqueness fails.

但是storeit [4357891223]返回一些其他对象实例而不是object3;因此 仍然有效,但唯一性失败。

#7


0  

I like to use generators for ids. Allow the generator to maintain a list of ids already used.

我喜欢使用生成器来进行ID。允许生成器维护已使用的ID列表。

# 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

Although this is not a memory effiecent way for huge in-memory datasets. If you wanted to use something like that then modify this to have the OS handle caching to a file... say via a named pipe.

虽然这不是大内存数据集的记忆效应方式。如果你想使用类似的东西,那么修改它以让操作系统处理缓存到文件...比如通过命名管道。

#1


5  

Are you aware of the id function in python, and could you use it instead of your counter idea?

你是否知道python中的id函数,你可以使用它而不是你的反思吗?

class C(): pass

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

#2


41  

Concise and elegant:

简洁优雅:

import itertools

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

#3


14  

First, use Uppercase Names for Classes. lowercase names for attributes.

首先,使用类的大写名称。属性的小写名称。

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

#4


11  

Using count from itertools is great for this:

使用来自itertools的count非常适合:

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

The same interface works if you later need to change how the values are generated, you just change the definition of id_generator.

如果稍后需要更改值的生成方式,则只需更改id_generator的定义即可使用相同的界面。

#5


1  

Ids sometimes benefit from using some fields of the object you wanted to reference. This is a old style database technique.

Ids有时会受益于使用您想要引用的对象的某些字段。这是一种旧式数据库技术。

for example if you have a app that keeps records for incoming customer phone calls, then possible use an id generated by time = some thing else

例如,如果您有一个应用程序来保留传入的客户电话呼叫的记录,那么可能使用由time =其他东西生成的id

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

only beaware the time.time() and time.clock() are individual computer return value unless on generated on the server. And if on the server make sure your server clock is set right; as always.

只知道time.time()和time.clock()是单独的计算机返回值,除非在服务器上生成。如果在服务器上确保您的服务器时钟设置正确;一如既往。

#6


0  

Another note on id() and rethinking other's answer about it. id() may return a unique number, if and only if it remembers every id ever returned even if an object is deleted; which it (id()) does not do. So therefore...

关于id()的另一个注释,并重新考虑其他人的答案。 id()可能会返回一个唯一的数字,当且仅当它记住所有返回的id,即使删除了一个对象;它(id())不做。因此......

In support of what others were saying that id() does not return a unique number; It is true that it can not guarentee a unique value if and only if you are storing those id() values as references to objects AND that you are deleting the instances of objects you are getting id()s for. BUT ! using id() as a reference means that you basically have an object that has a key linked somehow with another object.

支持其他人说id()不返回唯一的数字;确实,当且仅当您将这些id()值存储为对象的引用并且您正在删除您正在获取id()的对象的实例时,它才能保证唯一值。但是!使用id()作为引用意味着您基本上有一个对象,该对象具有以某种方式与另一个对象链接的键。

This is not invalidated by non-uniqueness of id(). It is only invalidated if you do not check if adding a new object has a preexisting id() already stored as a reference to some other instance of the object.

这不会因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 ] returns some other object instance not object3; therefore the < link > remains valid but the uniqueness fails.

但是storeit [4357891223]返回一些其他对象实例而不是object3;因此 仍然有效,但唯一性失败。

#7


0  

I like to use generators for ids. Allow the generator to maintain a list of ids already used.

我喜欢使用生成器来进行ID。允许生成器维护已使用的ID列表。

# 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

Although this is not a memory effiecent way for huge in-memory datasets. If you wanted to use something like that then modify this to have the OS handle caching to a file... say via a named pipe.

虽然这不是大内存数据集的记忆效应方式。如果你想使用类似的东西,那么修改它以让操作系统处理缓存到文件...比如通过命名管道。