繁体   English   中英

在枚举类中声明一个静态变量

[英]Declare a static variable in an enum class

我有一个颜色枚举。 我希望在枚举类中添加一个辅助方法“toRGB()”,将枚举的实例转换为 RGB 对象。 作为优化,我希望将字典创建一次作为静态变量。 然而,正确的语法似乎让我难以理解。

谁能提出正确的方法来做到这一点?

from enum import Enum

class RGB:
    def __init__(self, r, g, b):
        pass

class Color(Enum):
    RED = 0
    GREEN = 1

    __tbl = {
              RED:   RGB(1, 0, 0),
              GREEN: RGB(0, 1, 0)
            }

    def toRGB(self):
        return self.__class__.__tbl[self.value]

c = Color.RED
print(c.toRGB())

我收到以下错误:

Traceback (most recent call last):
  File "C:/Users/user/Desktop/test.py", line 20, in <module>
    print(c.toRGB())
  File "C:/Users/user/Desktop/test.py", line 17, in toRGB
    return self.__class__.__tbl[self.value]
TypeError: 'Color' object does not support indexing

从 Python 3.7 开始,使用_ignore_字段: https ://docs.python.org/3/library/enum.html

class Color(Enum):
    _ignore_ = ['_tbl']
    _tbl = {}  # nice for the type checker, but entirely ignored!


Color._tbl = {}  # actually creates the attribute

非方法属性成为枚举成员(甚至tbl )。 您可以改用关键字参数:

class Color(Enum):
    RED = 0
    GREEN = 1

    def toRGB(self, tbl={
        RED:   RGB(1, 0, 0),
        GREEN: RGB(0, 1, 0)
    }):
        return tbl[self.value]

或者,您可以在创建类后定义属性:

class Color(Enum):
    RED = 0
    GREEN = 1

    def toRGB(self):
        return self._tbl[self]

Color._tbl = {
    Color.RED:   RGB(1, 0, 0),
    Color.GREEN: RGB(0, 1, 0)
}

我们无法从您的示例中判断0 , 1 , 2 , ... 是有意义的值还是只是占位符,但如果它们只是占位符,那么最好的解决方案是丢弃它们并使用RGB值直接作为Enum成员值:

class Color(Enum):
    RED = 1, 0, 0
    GREEN = 0, 1, 0
    BLUE = 0, 0, 1

如果Enum成员的value与其rgb值不同,则可以使用新的 aenum 库并解决如下问题:

from aenum import Enum, NamedTuple

RGB = NamedTuple('RGB', 'r g b')

class Color(Enum, init='value rgb'):
    RED = 1, RGB(1,0,0)
    GREEN = 2, RGB(0,1,0)
    BLUE = 3, RGB(0,0,1)

并在使用中:

>>> Color.RED
<Color.RED: 1>

>>> Color.RED.rgb
RGB(r=1, g=0, b=0)

如果您想要的是类型转换,那么您可以使用RGB类作为枚举值:

from enum import Enum

class RGB:
    def __init__(self, r, g, b):
        # Check your inputs
        self.r = r
        self.g = g
        self.b = b

    def __str__(self):
        return f"{self.r} {self.g} {self.b}"

class Color(Enum):
    RED = RGB(1, 0, 0)
    GREEN = RGB(0, 1, 0)

    def toRGB():
        return c.value

c = Color.RED
print(c.toRGB())

您也可以跳过toRGB辅助方法并简单地编写Color.RED.value

Enum子类实现静态类变量的另一种方法是使用单例模式:

class Color(str, Enum):
    RED = "red"
    GREEN = "green"

    def __new__(cls, value):
        if not hasattr(cls, "instance"):
            cls.__tbl = {"red": RGB(1, 0, 0), "green": RGB(0, 1, 0)}
        obj = str.__new__(cls, value)
        return Enum.__new__(cls, obj)

请注意,您不能在__new__的定义中使用REDGREEN等枚举实例(它们尚不存在),因此我使用了字符串标识符。 一般来说,我更喜欢第一个解决方案。 我的代码看起来像这样,因为它需要只加载一次大型数据集。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM