У меня в Python 3.8.1 работает следующее:
@unique
class Encoder(IntFlag):
# H1 sensor signal
H1 = 0x00
# H2 sensor signal
H2 = 0x01
# H3 sensor signal
H3 = 0x02
Затем я пытаюсь поймать с помощью утверждения, если значение не находится в перечислении, т.е.
from enum import unique, IntFlag
signal = Encoder.H1
assert signal in iter(Encoder), f"Valid Encoder line is integer 0 to 2 inclusive."
Я заметил, что в Python 3.8 сигнал в iter (Encoder) возвращает True, но False в Python 3.12.4.
Это может быть изменение в какой-то версии с 3.8.1 на 3.12.4, но я не уверен, с чего начать, чтобы это работало в обеих.
enum.Flag
реализует __содержит__.
Чтобы проверить членство, позвоните iter
и просто используйте:
signal in Encoder
Это будет работать как в 3.8.1, так и в 3.12.4.
Примечание. Изменение поведения итерации флагов произошло в Python 3.11 и упоминается в журнале изменений здесь.
Кроме того, вам, вероятно, все равно следует использовать IntEnum
, а не IntFlag
. IntFlag
было бы уместно в случае использования, где Encoder.H2 | Encoder.H3
имело значение и означало «оба из них». В вашем случае Encoder.H2 | Encoder.H3
— недопустимое значение.
@Dunes Это комбинация этого и добавления Flag.__iter__
. Последний и предпоследний пункты в моей ссылке. Не знаю, как Итану удалось это изменить без периода устаревания, но мне это кажется обратным изменением.
Связано: github.com/python/cpython/issues/109633
Мне интересно, есть ли здесь регресс. Например, H0
считается членом перечисления и продолжает существовать как атрибут перечисления. Однако dir(Encoder)
больше не возвращает его имя. Это противоречит документации __dir__
, в которой говорится, что она возвращает всех членов — как канонических, так и псевдонимов.
Также стоит отметить, что __contains__
также возвращает true для любого значения составного флага, а не только для именованных флагов. например. assert (H2 | H3) in Encoder
, но assert (H2 | H3) not in Encoder.__members__
Изменение поведения итерации напрямую не упоминается в журнале изменений. Скорее,
H1
больше не считается канонической формой. Вместо этого он считается псевдонимом чего-то вродеH2 & H3
.