Перегрузка __getitem__ enum Python для возврата первого элемента кортежа - PullRequest
1 голос
/ 09 марта 2020

Я хотел перегрузить метод getitem Enum в Python, чтобы вернуть первый элемент кортежа вместо всего содержимого значения. Для этого я попытался создать Enum на основе EnumMeta с переопределенным методом, как показано ниже, а затем наследовать конечный класс Enum, как показано ниже:

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.')

Как мне удалось правильно перегрузить метод?

Ответы [ 3 ]

0 голосов
/ 09 марта 2020

Для этого вам не нужен новый метакласс, просто обычное наследование. __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, должен иметь значения, которые на самом деле , indexable и __getitem__ могут быть определены непосредственно в вашем Command классе, если вы не планируете делать несколько классов индексируемыми.)

0 голосов
/ 09 марта 2020

Документация по перечислениям дает хороший пример того, как хранить несколько констант в перечислении и получать к ним доступ через имя атрибута.

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
0 голосов
/ 09 марта 2020

Command.SUCCESS и SUCCESS.value - все атрибуты доступа, поэтому __getitem__ никогда не входит в изображение.

Если вы хотите, чтобы value было 0 (или 1, et c.) Затем вы хотите разделить 0, "Exited successsssfully" на две части - может быть value и __doc__? Чтобы увидеть нечто подобное, только сделанное с помощью stdlib Enum, попробуйте этот .

Что касается подклассов EnumMeta, , прочитайте это .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...