python3.5中内部类(enum)中静态/类列表/字典的初始化

2024-10-01 17:37:01 发布

您现在位置:Python中文网/ 问答频道 /正文

是否可以像其他变量一样在内部枚举类中初始化静态/类字典?在

# 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和{},以及所有可能的枚举(或其中任何有趣的子集)的列表。这样做的目的是要有一个列表,以便快速引用和迭代/枚举,而to-string可以是一个包含任何逻辑的arbritray方法。名字查找只是为了让问题变得清楚而简化。在


Tags: tonameselfstringisdefenumall
1条回答
网友
1楼 · 发布于 2024-10-01 17:37:01

这里的问题不是您有一个内部类,而是内部类是一个Enum;但是,有可能将非成员属性作为Enum类的一部分,有关详细信息,请参见this question and answer。在

总而言之,您需要使用某种描述符使ALL和{}以避免将它们转换为枚举成员:

# 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中:

^{pr2}$

这将避免您在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和{}被创建时,A和{}仍然是{},而{}没有{}方法。解决这一问题的简单方法是在尝试访问这些方法之前检索enum成员: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

相关问题 更多 >

    热门问题