【问题标题】:Declare a static variable in an enum class在枚举类中声明一个静态变量
【发布时间】:2016-03-15 05:25:35
【问题描述】:

我有一个颜色枚举。我希望在枚举类中添加一个辅助方法“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

【问题讨论】:

  • 我意识到这已经很老了,但要回答实际问题。 dunderscore 变量被忽略。所以你可以把它命名为__tbl__

标签: python python-3.x enums


【解决方案1】:

从 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

【讨论】:

  • 请注意,不幸的是,这不适用于 Pyright。它仍然认为_tblColor,即使你是_tbl: dict[...] = {}。最后我只是将_tbl 放在全局范围内:_color_tbl: dict[...] = {}; class Color(Enum): ...
【解决方案2】:

非方法属性成为枚举成员(甚至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)
}

【讨论】:

    【解决方案3】:

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

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

    如果Enum 成员的value 与其rgb 值分开,您可以使用new aenum library 并像这样解决问题:

    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)
    

    【讨论】:

      猜你喜欢
      • 2015-04-26
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多