在Python类中创建一个增量ID,每个子类都有自己的ID系列



我想创建一个类,其中类的每个对象都有一个从0开始的唯一序列ID。我还希望每个子类也有从0开始的顺序ID,编号不受父类或同级类的影响。

使用类似问题的答案,我创建了类Foo

class Foo:
id_iter = itertools.count()
def __init__(self):
self.id = next(self.id_iter)

Foo的所有实例都将具有一个连续的id值。我还想创建一个从Foo继承的类Bar,这样

>>> Foo().id
0
>>> Foo().id
1
>>> Foo().id
2
>>> Bar().id  # The first Bar id starts at 0 rather than 3
0

如果我创建类似于的Bar

class Bar(Foo):
def __init__(self):
super(Bar, self).__init__()

上面对Bar().id的调用将返回3,因为两个类都使用相同的迭代器。或者,我可以将id_iter = itertools.count()添加回我的Bar定义中,并获得我期望的输出。然而,我正在制作Foo的多个子类,不想在每个类中添加这一行;我希望Foo的所有子类都能自动继承ID功能,而不必向子类定义添加任何额外的内容。我怎样才能做到这一点?

不能对类属性执行此操作,因为类属性不是继承的。一种方法可以是使用一个单独的字典来记录类的计数。例如:

import itertools

class ClassCounter(object):
counters = {}
@classmethod
def get_counter(cls, class_to_count):
cls.counters.setdefault(class_to_count, itertools.count())
return next(cls.counters[class_to_count])

class Foo:
def __init__(self):
self.id = ClassCounter.get_counter(self.__class__)

class Bar(Foo):
def __init__(self):
super(Bar, self).__init__()

if __name__ == '__main__':
foo1 = Foo()
foo2 = Foo()
foo3 = Foo()
bar1 = Bar()
bar2 = Bar()
print(f"{foo1.id=}, {foo2.id=}, {foo3.id=}, {bar1.id=}, {bar2.id=}")

这应该打印:

foo1.id=0, foo2.id=1, foo3.id=2, bar1.id=0, bar2.id=1

最新更新