Странное поведение enum в python - PullRequest
0 голосов
/ 22 мая 2019

У меня есть следующее перечисление (оно сокращено, чтобы сделать примеры чище)

class ObjectNames(enum.Enum):
    full = 'full'

А этот:

class ObjectPoses(enum.Enum):
    front = 'front'
    left = 'left'
    right = 'right'

Эти два перечисления связаны следующим соотношением:

class ObjectNamePoseMatcher:
    match = {
        ObjectNames.full: [ObjectPoses.front, ObjectPoses.right, ObjectPoses.left],
}

Таким образом, он в основном создает связь между ObjectName и позой. Это настройка. В какой-то момент мой код завершается ошибкой с KeyError при попытке сделать поиск ObjectNamePoseMatcher.match. В частности, происходит сбой с этим сообщением об ошибке:

KeyError: <ObjectNames.full: 'full'> Здесь не получается:

ObjectNamePoseMatcher.match[self._object_name]

однако

>>self._object_name
<ObjectNames.full: 'full'>

и

>>ObjectNamePoseMatcher.match {<ObjectNames.full: 'full'>: [<ObjectPoses.front: 'front'>, <ObjectPoses.right: 'right'>, <ObjectPoses.left: 'left'>]}

Итак, ключ здесь. Это странно, поэтому я выполнил следующий фрагмент:

for k,v in ObjectNamePoseMatcher.match.items():
    print(k,k==self.object_name)
    print(hash(k)==hash(self.object_name))
    print(id(k)==id(self.object_name))
    print(id(type(k))==id(type(self.object_name)))

И это приводит к: ObjectNames.full False True False False Так что ObjectNames.full и self._object_name имеют одинаковый хеш, но разные типы, идентификаторы и идентификаторы типов. Но хэш такой же.

После этого я пошел на самое первое место, где установлено поле self._object_name. Снова выполнил тот же фрагмент, получил тот же результат. Я выполнил этот фрагмент после этой строки:

d.object_name = ObjectNames.full Однако, если в этой точке останова я повторно выполню эту строку

d.object_name = ObjectNames.full и затем выполнить вышеупомянутый фрагмент, я получаю следующий вывод:

ObjectNames.full True True True True Так что теперь хэш, идентификаторы и идентификаторы типов совпадают Без всякого резонанса я просто повторил ту же строку после остановки в точке останова.

Что здесь может пойти не так?

Спасибо

1 Ответ

0 голосов
/ 22 мая 2019

Я думаю, что вы хотите IntEnum не Enum. IntEnum s сравнивать по целочисленным значениям и, следовательно, по транзитивности по отношению к другим не связанным перечислениям. Вы явно ожидаете, что экземпляры ObjectNames и ObjectPoses будут сопоставимы, и я не думаю, что Enum s работает так.

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