如何迭代枚举的所有值,包括任何嵌套的枚举?

10
假设有两个从Enum派生的类,例如:
class Color(Enum):
    blue = 'blue'
    red = 'red'

class Properties(Enum):
    height = 'h'
    weight = 'w'
    colors = Color


什么是遍历嵌套Enum的最佳方法(可能是递归),例如上面示例中的Properties.colors,包括其中的Color.blueColor.red标签?需要检查值的类型吗?

你的意图不是很清楚。bluered应该都被视为Properties的成员吗?还是你想列出Properties.heightProperties.weightProperties.colors.blueProperties.colors.red - chepner
1
我认为你不想让“Properties”成为一个“Enum”,而是像“NamedTuple”这样的东西。 - Samwise
迭代应该通过值Properties.height,Properties.weight,Color.blue,Color.red运行。如果枚举嵌套更深,则迭代也应该通过这些值运行。@Samwise:我承认这个例子有点牵强,但我想尽可能保持简单。 - ctenar
在你的问题中,“enum-labels”确切指的是什么? - bad_coder
@bad_coder:Color有标签blueredProperties有标签height, weight, colors,但是我想将colors解析为它自己的标签,即blue, red - ctenar
@ctenar,这些被称为“枚举名称”,而不是标签。例如,Properties有一个名为height的“枚举成员”,其值为'h' - bad_coder
2个回答

5

这里有一个快速示例,仅打印它们。将其作为练习留给读者,使其成为通用生成器或适用于实际用例。

>>> from typing import Type
>>> def print_enum(e: Type[Enum]) -> None:
...     for p in e:
...         try:
...             assert(issubclass(p.value, Enum))
...             print_enum(p.value)
...         except (AssertionError, TypeError):
...             print(p)
...
>>> print_enum(Properties)
Properties.height
Properties.weight
Color.blue
Color.red

2

递归是最好的方法。这个例子比使用try except块更为简洁。

import inspect

def iter_enum(e):
  for member in e:  
    if inspect.isclass(member.value) and issubclass(member.value, enum.Enum):
        iter_enum(member.value)
    else:
        print(member)

iter_enum(Properties)

输出

Properties.height
Properties.weight
Color.blue
Color.red


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接