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
我需要类似枚举的样式来让 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