提问人:Martin 提问时间:10/11/2023 最后编辑:Martin 更新时间:10/12/2023 访问量:57
在 python 中列出所有枚举项(包括基类中的项)
List all Enum items (including the one from base class) in python
问:
我想用一个方法列出所有枚举项。该方法在基类中定义为类函数。 基类具有子类,子类具有其他子类。 我使用了 python 扩展 extendable-enum。
我更新了示例代码:
from enum import Enum
from extendableenum import inheritable_enum
import inspect
@inheritable_enum
class baseClass(Enum):
BASEELEMENT= 'Baseelement'
@classmethod
def list(cls):
classHierachy = inspect.getmro(cls)
for singleClass in classHierachy[0:-2]:
print(singleClass.__name__) # debug output
print(list(map(lambda singleClass: singleClass.name, eval(singleClass.__name__))))
def get_list_with_bases(class1, output=None):
if output is None:
output = []
try:
names = list(class1)
except TypeError:
return output
for class2 in class1.__bases__:
get_list_with_bases(class2, output)
output.extend(names)
return output
@inheritable_enum
class middleClass(baseClass):
MIDDLECLASSELEMENT = 'middleClassElement'
class endClass(middleClass, baseClass):
ENDCLASSELEMENT = 'endClassElement'
print(endClass.BASEELEMENT)
print(endClass.MIDDLECLASSELEMENT)
print(endClass.ENDCLASSELEMENT)
endClass.list()
# endClass.get_list_with_bases(endClass)
预期输出:
baseClass.BASEELEMENT
middleClass.MIDDLECLASSELEMENT
endClass.ENDCLASSELEMENT
endClass
['ENDCLASSELEMENT']
middleClass
MIDDLECLASSELEMENT
baseClass
BASEELEMENT
但我得到:
baseClass.BASEELEMENT
middleClass.MIDDLECLASSELEMENT
endClass.ENDCLASSELEMENT
endClass
['ENDCLASSELEMENT']
middleClass
[]
baseClass
[]
答:
2赞
Dakolas
10/11/2023
#1
根据项目存储库中提供的示例,它看起来无法以这种方式访问
https://github.com/gweesip/extendable-enum/blob/main/docs/examples/example_inheritable_enum.py
# And create a subclass with new members
class MoreFruit(Fruit):
MANGO = 4
DRAGONFRUIT = 5
# Only the non-inherited members will be in _member_names_
print(MoreFruit._member_names_)
# Inherited members are not included in dir, len, reversed or iteration
print(dir(MoreFruit))
print(len(MoreFruit))
print([member for member in reversed(MoreFruit)])
print([member for member in MoreFruit])
# Inherited members can not be accessed by name
try:
MoreFruit['APPLE']
except KeyError:
print('Access to super members by name not supported')
# or by value
try:
MoreFruit(1)
except ValueError:
print('Access by value not allowed')
# but can still be accessed as attributes.
print(MoreFruit.APPLE)
# The returned members are the superclass members.
print(MoreFruit.APPLE is Fruit.APPLE)
1赞
pts
10/11/2023
#2
根据 @Dakolas 的回答,没有直接的方法可以列出所有枚举名称。
用作解决方法:.__bases__
# And create a subclass with new members
class MoreFruit(Fruit):
MANGO = 4
DRAGONFRUIT = 5
print(list(MoreFruit) + list(MoreFruit.__bases__[0]))
作为更通用的解决方案,编写一个递归函数来访问所有级别的所有基类:
def get_list_with_bases(class1, output=None):
if output is None:
output = []
try:
names = list(class1)
except TypeError:
return output
for class2 in class1.__bases__:
get_list_with_bases(class2, output)
output.extend(names)
return output
# And create a subclass with new members
class MoreFruit(Fruit):
MANGO = 4
DRAGONFRUIT = 5
print(get_list_with_bases(MoreFruit))
评论
0赞
Martin
10/12/2023
嗨,pts,递归函数在我这边不起作用。我收到错误:NameError:未定义名称“get_list_with_bases”。
0赞
pts
10/12/2023
它对我有用,也许你复制粘贴不正确。
1赞
Grismar
10/11/2023
#3
如果您试图理解代码的问题,它通常有助于使代码更简单。
这与你的代码非常相似,但大大简化了:
from enum import Enum
from extendableenum import inheritable_enum
@inheritable_enum
class ExampleA(Enum):
A = 1
class ExampleAB(ExampleA):
B = 2
print(ExampleAB.A, ExampleAB.A.value)
print(ExampleAB.B, ExampleAB.B.value)
for x in ExampleAB:
print('x:', x)
不是多个类添加东西,而是有一个简单的基类,它只有 value 。以及其中也具有 value 的派生类。ExampleA
A
1
ExampleAB
B
2
而不是你拥有的方法,它可以像用户@Barmar在评论中指出的那样写成这样:
@classmethod
def list(cls):
return list(map(lambda c: c.name, cls))
我刚刚在末尾添加了一个简单的循环,该循环还遍历枚举中的所有内容并显示里面的内容。for
输出:
ExampleA.A 1
ExampleAB.B 2
x: ExampleAB.B
这清楚地表明:
ExampleAB
确实使这两个类的值都可用。- 的实际值仍然来自超类。
ExampleAB.A
ExampleA.A
- 如果遍历 ExampleAB,它实际上只包含 ,它不会包含基类中的值。
ExampleAB.B
但是,如果您只想要此功能,那么 a 当然会是一个更简单、更好的选择:dict
exampleA = {
'A': 1
}
exampleAB = exampleA | {
'B': 2
}
print(exampleAB['A'])
print(exampleAB['B'])
for x in exampleAB:
print('x:', x, 'value:', exampleAB[x])
输出:
1
2
x: A value: 1
x: B value: 2
评论
0赞
Martin
10/12/2023
嗨,格里斯玛,我想得到所有等级的枚举。我用这个函数尝试了一下,但结果是一样的。即使我单独针对每个班级:我也会将其作为回复发布
评论
eval(cls.__name__)
cls
dict
extendable-enum