Class 为属性自动生成唯一增量整数值(与 'enum.auto()' 相同)

Class with auto-generated unique incremental integer values for attributes (the same as 'enum.auto()' do)

我需要类似枚举的样式来让 class 自动生成值。我不能使用 Enum,因为我需要可变性,换句话说,我需要在运行时添加属性。

伪代码:

def auto(attribute_name: str) -> int:
    # Calculate a value for an attribute...
    # E.g. the first attribute will have "1", the second will have "2", etc.
    return value


class Something:
    foo = auto()  # Must be auto-assigned as 1
    bar = auto()  # Must be auto-assigned as 2
    spam = auto()  # Must be auto-assigned as 3
    eggs = auto()  # Must be auto-assigned as 4


assert Something.foo == 1
assert Something.bar == 2
assert Something.spam == 3
assert Something.eggs == 4

Something.add("new_attribute")
assert Something.new_attribute == 5

我想确保我不会通过编写大量自定义代码来重新发明轮子。有什么常见的解决方法吗?

enum.auto实际上不是计数器。它只是产生一个哨兵值,由 enum.Enum 机器转换为计数器 或类似的

虽然没有这种机制的直接 re-useable、public 变体,但编写您自己的变体很简单:

auto = object()


class AttributeCounter:
    """Baseclass for classes enumerating `auto` attributes"""
    # called when creating a subclass via `class Name(AttributeCounter):`
    def __init_subclass__(cls, **kwargs):
        cls._counter = 0
        # search through the class and count up `auto` attributes
        for name, value in cls.__dict__.items():
            if value is auto:
                cls.add(name)

    @classmethod
    def add(cls, name: str):
        """Add attribute `name` with the next counter value"""
        count = cls._counter = cls._counter + 1
        setattr(cls, name, count)

auto 值是“计数属性”的任意标记;如果需要的话,可以把它变成一个函数,甚至 re-use enum.auto.

使用 __init_subclass__enum 使用的元类魔术的轻量级替代方法。 Similar to enum's use of _generate_next_value_,它提供了通用机制,但允许通过替换单个方法来覆盖逻辑 add


类似于enum.Enum,通过继承将计数器功能添加到您自己的类型中:

class Something(AttributeCounter):
    foo = auto
    bar = auto
    spam = auto
    eggs = auto


assert Something.foo == 1
assert Something.bar == 2
assert Something.spam == 3
assert Something.eggs == 4

Something.add("new_attribute")
assert Something.new_attribute == 5