[英]Set unique id for each object in Python
I need to make class, for which each instantiated object will have unique id (simply incremented counter). 我需要创建类,对于该类,每个实例化的对象都将具有唯一的ID(仅增加计数器)。 For now, all 3 objects(b, b1, b2) shares one A.__COUNTER variable. 现在,所有三个对象(b,b1,b2)共享一个A .__ COUNTER变量。
class A(type):
__COUNTER = 0
def __call__(cls, *args, **kwargs):
setattr(cls, "id", A.__COUNTER)
A.__COUNTER += 1
return type.__call__(cls, *args, **kwargs)
class B():
__metaclass__ = A
def __init__(self):
self.id
b = B()
b1 = B()
b2 = B()
print(b.id, b1.id, b2.id) -> (2, 2, 2)
Seems like I am digging in wrong direction 好像我挖错了方向
PS SOLVED PS 解决了
Sorry, guys, I did not mentioned that there can be couple classes which should share same id sequence. 抱歉,伙计们,我没有提到可以有几个应该共享相同ID序列的类。 There are bunch of solutions, here how I solved it 有很多解决方案,这是我如何解决的
class A(type):
__COUNTER = 0
def __call__(cls, *args, **kwargs):
obj = type.__call__(cls, *args, **kwargs)
obj.setId(A.__COUNTER)
A.__COUNTER += 1
return obj
class B():
__metaclass__ = A
def setId(self, id):
self.id = id
class C():
__metaclass__ = A
def setId(self, id):
self.id = id
b = B()
b1 = B()
b2 = B()
c = C()
b3 = B()
print(b.id, b1.id, b2.id, c.id, b3.id) -> (0, 1, 2, 3, 4)
Well, all objects in Python already have a unique id 好吧,Python中的所有对象已经具有唯一的ID
>>> id("a string")
140588614961168
But if you want a separate counter, the method you use should work. 但是,如果您想要一个单独的计数器,则可以使用您使用的方法。 More information on WHY you want this could help though. 但是,有关为什么您希望这样做的更多信息可能会有所帮助。
You can just use a class variable instead: 您可以只使用类变量:
class B ():
__lastId = 1
def __init__ (self):
self.id = B.__lastId
B.__lastId += 1
>>> [B().id for _ in range(10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
As described in What is a metaclass? 如什么是元类中所述? , a meta class is the class of a class, whereas you just want to modify the actually instantiated objects of a single type. ,元类是类的类,而您只想修改单个类型的实际实例化的对象。 So there's no need to go deep into the metaclass complexity level here. 因此,这里无需深入了解元类的复杂性级别。
A good solution depends on the use case. 一个好的解决方案取决于用例。 I've provided a very generic one. 我提供了一种非常通用的。
IDAssigner
is a factory that sticks an ID onto everything is creates. IDAssigner
是将ID粘贴到创建的所有内容上的工厂。 Create an instance of IDAssigner
for a new pool of IDs. 为新的ID池创建IDAssigner
实例。 You call an instance of IDAssigner
passing the class to instantiate as the first argument, followed by arguments for the class's __init__
method. 您调用IDAssigner
的实例,该实例将类实例化为第一个参数,后跟该类的__init__
方法的参数。
from itertools import count
class IDAssigner(object):
def __init__(self):
self._next_id = count()
def __call__(self, klass, *args, **kwargs):
obj = klass(*args, **kwargs)
setattr(obj, 'id', next(self._next_id))
return obj
class Foo(object):
def __init__(self, value):
self.value = value
def __str__(self):
return self.value
create = IDAssigner()
foo_1 = create(Foo, 'Hello')
foo_2 = create(Foo, 'World')
print(foo_1, foo_1.id)
print(foo_2, foo_2.id)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.