Инициализировать переменную с помощью перечисления с повторяющимися значениями

#python #python-3.x

#python #python-3.x

Вопрос:

У меня есть класс Enum с повторяющимися значениями. Каждое значение в примере представляет размер регистра в битах. Я хочу инициализировать переменную по имени перечисления. Поскольку они имеют одинаковое значение, похоже, что Python принимает первое вхождение, игнорируя имя перечисления, которое я передал.

 from enum import Enum
class OperandType(Enum):
    EAX = 32
    EBX = 32
   
ebx = 'EBX'
new_op = OperandType[ebx]
print(new_op)
  

Здесь будет напечатано:

 OperandType.EAX
  

Как заставить ее работать так, как я ожидаю?

Комментарии:

1. Вместо перечисления просто используйте статический постоянный класс значений

Ответ №1:

Согласно документам:

Перечисление — это набор символических имен (членов), привязанных к уникальным постоянным значениям.

Таким образом, имена, которые указывают на одно и то же значение, будут рассматриваться как псевдонимы друг друга. Также смотрите https://docs.python.org/3.9/library/enum.html#duplicating-enum-members-and-values:

Учитывая два элемента A и B с одинаковым значением (и определенным первым), B является псевдонимом A. Поиск по значению значений A и B вернет A. Поиск по имени B также вернет A.

В вашем случае EAX она была определена первой и имеет то же значение, EBX что и, поэтому поиск EBX дал вам EAX .

Что касается того, как заставить ее работать так, как вы ожидаете: невозможно, потому что перечисления так не работают.

Конечно, вы можете создать сопоставление, подобное этому:

 SIZES = {OperandType.EAX: 32, OperandType.EBX: 32}
  

… а затем запросить размеры через SIZES[OperandType.EAX] .

Комментарии:

1. Правильно. Это поведение реализовано в ____new____ function

Ответ №2:

Это также будет работать, потому что экземпляры класса / значения перечисления уникальны:

 class OperandSize:
    def __init__(self, size):
    self._operand_size = size

class OperandType(Enum):
    EAX = OperandSize(32)
    AAA = OperandSize(32)