Сопоставление шаблонов в Python для перехвата комбинации флагов перечисленияPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Сопоставление шаблонов в Python для перехвата комбинации флагов перечисления

Сообщение Anonymous »

При использовании флагов в Python сопоставление с образцом фиксирует только прямое равенство, а не включение. Однако его можно обойти с помощью условия и in, при условии, что вы перед этим поймаете флаг 0, если считаете, что это особый случай:

Код: Выделить всё

from enum import Flag

class Test(Flag):
ONE = 1
TWO = 2
THREE = ONE | TWO
NONE = 0

def match_one(pattern):
match pattern:
case Test.THREE:
print(pattern, 'Three')
case Test.ONE:
print(pattern, 'ONE')
case v if v in Test.THREE:
print(pattern, 'in THREE')
case _:
print(pattern, 'Other')
Тест. ОДИН ОДИН

Тест. ДВА в ТРИ

Тест. ТРИ Три

Test.NONE в THREE

Однако использование такого условия ограничивает использование нескольких флагов.
Минимальным примером может быть попытка сопоставить OBJ_1 с TYPE_1 (ATTR_1, ATTR_2 или TYPE_1) или OBJ_2 с TYPE_2 (ATTR_3, ATTR_4 или TYPE_2) (проблема не ограничивается таким простым случаем, но это хорошее минимальное представление)

Код: Выделить всё

class Flag_1(Flag):
OBJ_1 = 1
OBJ_2 = 2
NONE = 0

class Flag_2(Flag):
ATTR_1 = 1
ATTR_2 = 2
ATTR_3 = 4
ATTR_4 = 8
TYPE_1 = ATTR_1 | ATTR_2
TYPE_2 = ATTR_3 | ATTR_4
NONE = 0
что можно сделать как

Код: Выделить всё

match flag1, flag2:
case Flag_1.NONE, _ | _, Flag_2.NONE:
print('Useless')
case (Flag_1.OBJ_1, c) if c in Flag_1.TYPE_1:
print('Do 1')
case (Flag_1.OBJ_2, c) if c in Flag_1.TYPE_2:
print('Do 1')
case _:
print('Other stuff')
или

Код: Выделить всё

match flag1, flag2:
case Flag_1.NONE, _ | _, Flag_2.NONE:
print('Useless')
case (Flag_1.OBJ_1, Flag_2.ATTR_1 | Flag_2.ATTR_2) \
| (Flag_1.OBJ_2, Flag_2.ATTR_3 | Flag_2.ATTR_4):
print('Do 1')
case _:
print('Other stuff')
Однако решение 1 ограничено, поскольку имеется еще несколько комбинаций и добавляется много строк, повторяющих одну и ту же операцию. Решение 2, с другой стороны, ограничено, если TYPE_1 содержит, скажем, 10 флагов, поскольку это будет очень длинная строка.
что-то подобное ниже невозможно при сопоставлении с образцом ( и, я думаю, будет более адаптирован к оператору if)

Код: Выделить всё

case (Flag_1.OBJ_1, c) if c in Flag_2.TYPE_1 \
| (Flag_1.OBJ_2, c) if c in Flag_2.TYPE_2:  # invalid syntax
и следующее не работает, как объяснялось ранее, из-за способа сопоставления шаблонов.

Код: Выделить всё

case (Flag_1.OBJ_1, Flag_2.TYPE_1) \
| (Flag_1.OBJ_2, Flag_2.TYPE_2) \
Есть ли лучший способ, чем решение 1, выполнять один случай для каждой комбинации, несмотря на то, что все они имеют одинаковый результат, или использовать оператор if для сопоставления объединенных Флаг?


Подробнее здесь: https://stackoverflow.com/questions/789 ... ombination
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»