Initialization of static/class lists/dictionaries in inner class(enum) in Python 3.5
是否可以像其他变量一样在内部枚举类中初始化静态/类字典?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | # 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() |
类
这里的问题不是您有一个内部类,而是内部类是一个
综上所述,您需要使用某种描述符使
1 2 3 4 5 6 7 8 9 10 | # 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) |
然后在你的电脑里1〔4〕:
1 2 3 4 5 | ALL = classattribute([A, B]) NAMES = classattribute({ A :"some_name_other_than_enum_a_name", B :"some_name_other_than_enum_b_name", }) |
这将避免您在
1 | AttributeError: 'int' object has no attribute 'to_string' |
其原因是构建
收集所有定义:
{
'A':1,
'B':2,
'ALL':classattribute([A, B]),
'NAMES':classattribute({'A':..., 'B':...}),
'to_string':method(...),
}将不是
__dunder__ 、_sunder_ 或descriptor 的任何内容转换为枚举成员:A -> 。B -> 。
这意味着,在创建
要将它们组合在一起,您的代码应该是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # 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 3 | [1, 2] some_name_other_than_enum_a_name some_name_other_than_enum_b_name |