[英]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__
的定义中使用RED
、 GREEN
等枚举实例(它们尚不存在),因此我使用了字符串标识符。 一般来说,我更喜欢第一个解决方案。 我的代码看起来像这样,因为它需要只加载一次大型数据集。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.