【问题标题】:Overloading __getitem__ enum Python to return the first element of a tuple重载 __getitem__ 枚举 Python 以返回元组的第一个元素
【发布时间】:2020-03-09 16:54:10
【问题描述】:

我想重载 Python 中的 getitem 枚举方法以返回元组的第一个元素而不是整个值内容。为此,我尝试使用重新定义的方法创建一个基于 EnumMeta 的 Enum,如下所示,然后继承自它的 Enum final 类,如下所示:

from enum import Enum
from enum import EnumMeta
from datetime import date

class CommandMeta (EnumMeta):
    SUCCESS = 0, "Exited successsssfully."

    def __getitem__(cls, value, *args, **kwargs):
        value = value[0]
        return super().__getitem__(value, *args, **kwargs)

class Command (Enum, metaclass=CommandMeta):
    SUCCESS = 0, "Exited successsssfully."

预期的输出是:

print(Command.SUCCESS.value)
0

相反,它仍然是一样的:

print(Command.SUCCESS.value)
(0, 'Exited successsssfully.')

我怎样才能正确地重载方法?

【问题讨论】:

  • 你被误导了,阅读object.__getitem__
  • 感谢您的回答,我认为我应该做的是让 value=cls[value]?

标签: python enums


【解决方案1】:

你不需要一个新的元类,只需要普通的继承。 __getitem__ 仅在您使用索引语法时被调用。

class IndexableEnum(Enum):
    def __getitem__(self, key):
        return self.value[key]

class Command(IndexableEnum):
    SUCCESS = 0, "Exited successfully"

然后

>>> Command.SUCCESS
<Command.SUCCESS: (0, 'Exited successfully')>
>>> Command.SUCCESS[0]
0

(当然,从IndexableEnum 继承的类实际上应该具有可索引的值,如果您不打算使多个类可索引,则可以直接在您的Command 类中定义__getitem__ .)

【讨论】:

    【解决方案2】:

    关于枚举的文档提供了一个good example 说明如何在一个枚举上存储多个常量,并通过属性名称访问它们。

    class Planet(Enum):
        MERCURY = (3.303e+23, 2.4397e6)
        VENUS   = (4.869e+24, 6.0518e6)
        EARTH   = (5.976e+24, 6.37814e6)
        MARS    = (6.421e+23, 3.3972e6)
        JUPITER = (1.9e+27,   7.1492e7)
        SATURN  = (5.688e+26, 6.0268e7)
        URANUS  = (8.686e+25, 2.5559e7)
        NEPTUNE = (1.024e+26, 2.4746e7)
        def __init__(self, mass, radius):
            self.mass = mass       # in kilograms
            self.radius = radius   # in meters
        @property
        def surface_gravity(self):
            # universal gravitational constant  (m3 kg-1 s-2)
            G = 6.67300E-11
            return G * self.mass / (self.radius * self.radius)
    

    访问时是这样的:

    >>> Planet.EARTH.value
    (5.976e+24, 6378140.0)
    >>> Planet.EARTH.mass
    5.976e+24
    >>> Planet.EARTH.surface_gravity
    9.802652743337129
    

    【讨论】:

      【解决方案3】:

      Command.SUCCESSSUCCESS.value 都是属性访问,所以__getitem__ 从不进图。

      如果您希望value 成为0(或1 等),那么您想将0, "Exited successsssfully" 分成两部分——也许value and __doc__?要查看类似的内容,仅使用 stdlib Enum 完成,请尝试 this one

      至于子类化EnumMetaplease read this

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-22
        • 1970-01-01
        • 2021-08-21
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 2011-07-12
        • 1970-01-01
        相关资源
        最近更新 更多