You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动