Python中如何将自定义枚举转为列表?如何检查值是否属于枚举?
搞定自制枚举的列表转换与值检查问题
嘿,先看看你写的这个自定义枚举实现:
def make_enum(**enums): return type('Enum', (), enums) an_enum = make_enum(first=1, second=2)
这里的an_enum其实是个动态生成的类,不是Python标准库enum.Enum那种正经枚举实例,所以得针对性处理值的提取和检查。
先解决:把枚举转成列表
要把它的枚举值转成列表,核心就是提取这个类里你自定义的属性值,过滤掉那些Python自带的双下划线开头的内置属性(比如__name__、__module__这些)。写个小函数就行:
def to_list(enum_obj): # 遍历类的属性字典,只保留非内置属性的值 return [value for key, value in vars(enum_obj).items() if not key.startswith('__')] # 用起来就是你之前的写法: assert 1 in to_list(an_enum) # 完全没问题 print(to_list(an_enum)) # 输出 [1, 2]
更高效的:直接检查值是否属于枚举
其实没必要先转成列表再检查,直接操作属性值会更快,尤其是需要多次检查的场景:
方法1:写个检查函数
def is_valid_enum_value(value, enum_obj): # 收集所有自定义枚举值 enum_values = [v for k, v in vars(enum_obj).items() if not k.startswith('__')] return value in enum_values # 测试一下 assert is_valid_enum_value(1, an_enum) # 没问题 assert is_valid_enum_value(3, an_enum) # 这里会触发断言错误,符合预期
方法2:预存成集合(更快的检查速度)
如果要多次判断,把枚举值存成集合更高效——集合的in操作是O(1),列表是O(n):
# 提前把值存成集合 an_enum_value_set = {v for k, v in vars(an_enum).items() if not k.startswith('__')} # 直接检查就行 assert 1 in an_enum_value_set assert 2 in an_enum_value_set assert 3 not in an_enum_value_set
额外建议:用Python标准库的enum.Enum
其实Python自带了enum模块,用它定义枚举更规范,还自带一堆便利功能,比如自动的成员检查、双向映射(名字找值,值找名字):
from enum import Enum class AnEnum(Enum): first = 1 second = 2 # 检查值是否在枚举里的方式 assert 1 in [member.value for member in AnEnum] # 或者更直接——如果值不存在会直接抛ValueError,也能起到检查作用 assert AnEnum(1) is AnEnum.first
这样就不用自己手写make_enum函数了,标准库的实现更健壮,还能避免很多潜在问题。
内容的提问来源于stack exchange,提问作者User12547645




