简体   繁体   English

在 Python class 中创建一个增量 ID,子类各自维护自己的 ID 系列

[英]Create an incremental ID in a Python class with subclasses each maintaining their own ID series

I want to create a class wherein each object of the class is given a unique sequential ID starting at 0 .我想创建一个 class,其中 class 的每个 object 都被赋予一个从0开始的唯一顺序 ID。 I also want each subclass to have sequential IDs starting at 0 as well, with numbering unaffected by parent or sibling classes.我还希望每个子类都具有从0开始的顺序 ID,编号不受父类或兄弟类的影响。

Using the answer to a similar question, I've created the class Foo使用类似问题的答案,我创建了 class Foo

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

All instances of Foo will have a sequential id value. Foo的所有实例都将具有顺序id值。 I also want to create a class Bar that inherits from Foo such that我还想创建一个 class Bar继承自Foo这样

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

If I create Bar like:如果我像这样创建Bar

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

The above call to Bar().id would return 3 because both classes are using the same iterator.上面对Bar().id的调用将返回3 ,因为两个类都使用相同的迭代器。 Alternatively, I could add id_iter = itertools.count() back into my Bar definition and get the output I'm expecting.或者,我可以将id_iter = itertools.count()添加回我的Bar定义并获得我期望的 output。 However, I'm making multiple subclasses of Foo , and don't want to have to add that line to each class;但是,我正在制作Foo的多个子类,并且不想将该行添加到每个 class; I want all subclasses of Foo to automatically inherit the ID functionality without having to add anything extra to the subclass definition.我希望Foo的所有子类都自动继承 ID 功能,而不必向子类定义添加任何额外内容。 How can I achieve this?我怎样才能做到这一点?

You can't do this with a class attribute as class attributes are not inherited.您不能使用 class 属性执行此操作,因为 class 属性不会被继承。 One method could be to use a separate dictionary for keeping count of classes.一种方法可能是使用单独的字典来保持类的计数。 For example:例如:

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=}")

This should print:这应该打印:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM