是否可以像其他变量一样在内部枚举类中初始化静态/类字典?
# file Outer.py
from enum import Enum
class Outer:
def callInner(self):
all_a = Outer.Inner.ALL
print(all_a) # prints Inner.ALL instead of the list
all_b = Outer.Inner.ALL[:] # TypeError Inner is not subscriptable
for e in all_a: #Inner is not iterable
print(e.to_string())
class Inner(Enum):
A = 1
B = 2
ALL = [A,B]
NAMES = {A : "some_name_other_than_enum_a_name",
B : "some_name_other_than_enum_b_name"}
def to_string(self):
return Outer.Inner.NAMES[self.value]
if __name__ == '__main__':
o = Outer()
o.callInner()
类Outer
是包含所有逻辑的模块。 Inner
类是一个枚举,它包含枚举键值对 A=1
和 B=2
以及所有可能的枚举(或其任何有趣的子集)。这个想法是有一个用于快速引用和迭代/枚举的列表,而 to_string 可以是包含任何逻辑的 arbritray 方法。名称查找只是为了使问题更清晰而进行的简化。
最佳答案
这里的问题不是你有一个内部类,而是内部类是 Enum
;但是,可以将非成员属性作为Enum
的一部分。类--参见this question and answer了解详情。
总而言之,您需要创建 ALL
和NAMES
使用某种描述符以避免将它们转换为枚举成员:
# inherit from `object` if using Python 2
class classattribute: # was called Constant in the linked answer
def __init__(self, value):
self.value = value
def __get__(self, *args):
return self.value
def __set__(self, _, value):
self.value = value
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.value)
然后在你的Inner
中:
ALL = classattribute([A, B])
NAMES = classattribute({
A : "some_name_other_than_enum_a_name",
B : "some_name_other_than_enum_b_name",
})
这将避免您在 callInner()
中遇到的错误方法,但会在print(e.to_string())
处添加一个新的行:
AttributeError: 'int' object has no attribute 'to_string'
这样做的原因是构建 Enum
是一个由两部分组成的过程:
收集所有定义:
{ 'A':1, 'B':2, 'ALL':classattribute([A, B]), 'NAMES':classattribute({'A':..., 'B':...}), 'to_string':method(...), }
改变任何不属于
__dunder__
的东西,_sunder_
,也不是descriptor
进入枚举成员:-
A
-><Inner.A: 1>
-
B
-><Inner.B: 2>
-
这意味着当 ALL
和NAMES
正在创建,A
和B
仍然int
s,和int
没有 to_string
方法。解决这个问题的简单方法是在尝试访问这些方法之前检索枚举成员:self.Inner(e).to_string()
.
将所有内容整合在一起,您的代码应如下所示:
# file Outer.py
from enum import Enum
class classattribute:
def __init__(self, value):
self.value = value
def __get__(self, *args):
return self.value
def __repr__(self):
return '%s(%r)' % (self.__class__.__name__, self.value)
class Outer:
def callInner(self):
all_a = Outer.Inner.ALL
print(all_a)
all_b = Outer.Inner.ALL[:]
for e in all_a: #Inner is not iterable
print(self.Inner(e).to_string())
class Inner(Enum):
A = 1
B = 2
ALL = classattribute([A,B])
NAMES = classattribute(
{A : "some_name_other_than_enum_a_name",
B : "some_name_other_than_enum_b_name"}
)
def to_string(self):
return Outer.Inner.NAMES[self.value]
if __name__ == '__main__':
o = Outer()
o.callInner()
运行时,您将得到以下结果:
[1, 2]
some_name_other_than_enum_a_name
some_name_other_than_enum_b_name
关于python - Python 3.5 内部类(枚举)中静态/类列表/字典的初始化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34465739/