Python 使用自动值的简洁语法创建StringAutoEnum类
我正在尝试实现一个StringAutoEnum类,它可以将其成员值设置为成员名称的小写版本,而不必为每个值调用auto(),因为这太冗长了,我不喜欢它 假设此基本Python 使用自动值的简洁语法创建StringAutoEnum类,python,python-3.x,enums,Python,Python 3.x,Enums,我正在尝试实现一个StringAutoEnum类,它可以将其成员值设置为成员名称的小写版本,而不必为每个值调用auto(),因为这太冗长了,我不喜欢它 假设此基本StringAutoEnum类: import aenum class StringAutoEnum(aenum.Enum): def _generate_next_value_(name, start, count, last_values): return name.lower() 理想情况如下: cla
StringAutoEnum
类:
import aenum
class StringAutoEnum(aenum.Enum):
def _generate_next_value_(name, start, count, last_values):
return name.lower()
理想情况如下:
class Animal(StringAutoEnum):
DOG, CAT, SNAKE
以确保以下情况属实:
Animal.DOG.value == "dog"
Animal.CAT.value == "cat"
Animal.SNAKE.value == "snake"
显然,上面的类定义甚至不是有效的python代码(除非已经预先定义了DOG、CAT和SNAKE),所以这样做(据我所知)是不可能的
因此,我考虑的几个备选方案如下:
分配给多个变量:
class Animal(StringAutoEnum):
DOG = CAT = SNAKE = auto()
可拆箱:
class Animal(StringAutoEnum):
DOG, CAT, SNAKE = auto()
重申一下,我不想这样做:
class Animal(StringAutoEnum):
DOG, CAT, SNAKE = auto(), auto(), auto()
我也不想使用函数式API
分配给多个变量的问题似乎是,auto()对于第一个变量名只计算一次,因此枚举的所有3个成员都以名称“DOG”和值“DOG”结束。我还没有找到解决这个问题的办法
iterable解包的问题是,我想不出任何方法来提前知道赋值运算符左侧有多少个变量
这意味着,虽然这将起作用,并将完全满足我的要求:
class Auto(aenum.auto):
def __iter__(self):
return iter([Auto() for _ in range(3)])
class Animal(StringAutoEnum):
DOG, CAT, SNAKE = Auto()
不幸的是,这不会:
class Animal(StringAutoEnum):
DOG, CAT, SNAKE, EMU = Auto()
我想不出任何办法来解决这个问题,分配给任意数量的成员
有没有人能想出一种简洁明了的方法来解决这个问题?或者,有人能提出一个可行的多变量赋值实现方案吗
提前谢谢 既然您正在使用,您就可以选择AutoEnum
——它充分体现了元类的魔力:
from aenum import AutoEnum
class StringAutoEnum(AutoEnum):
#
def _generate_next_value_(name, start, count, last_values):
return name.lower()
class Animal(StringAutoEnum):
DOG, CAT, SNAKE
--> list(Animal)
[<Color.Dog: 'dog'>, <Color.CAT: 'cat'>, <Color.SNAKE: 'snake'>]
从aenum导入自动枚举
类StringAutoEnum(自动枚举):
#
定义生成下一个值(名称、开始、计数、最后一个值):
返回name.lower()
动物类(StringAutoEnum):
狗、猫、蛇
-->名单(动物)
[, ]
如果这太神奇了,下一个最好的解决方案是对每个值使用
auto()
(或使用函数API)。这可以通过标准库轻松实现:
从枚举导入枚举
类StringAutoEnum(str,Enum):
@静力学方法
定义生成下一个值(名称*):
返回name.lower()
Animal=StringAutoEnum('Animal'、'DOG-CAT-SNAKE')
列表(动物)
[, ]
新类的第二个参数也可以是iterable而不是string
使用
str
mixin类型不是必需的,但允许您直接将枚举值(在本例中为小写名称)作为字符串使用,而无需先强制转换它们 哇。我真不敢相信我竟然不知道AutoEnum类。它基本上是完美的!您所描述的方法的唯一缺点是linters不喜欢它,因此您必须#noqa这一行。我在问题中提到,我不想使用函数API。原因是代码内省引擎和IDE通常无法理解以这种方式声明的枚举,因此您最终会失去通过使用类语法声明枚举而获得的自动完成和linting功能,这是使用枚举而不仅仅是“魔术字符串”的一半原因。
>>> list(Animal)
[<Animal.DOG: 'dog'>, <Animal.CAT: 'cat'>, <Animal.SNAKE: 'snake'>]