Преобразование нескольких проверок isinstance в структурное сопоставление с образцом
Я хочу преобразовать этот существующий код для использования сопоставления с образцом:
if isinstance(x, int):
pass
elif isinstance(x, str):
x = int(x)
elif isinstance(x, (float, Decimal)):
x = round(x)
else:
raise TypeError('Unsupported type')
Как вы пишете проверки isinstance с сопоставлением с образцом и как вы тестируете несколько возможных типов, таких как
(float, Decimal)
в то же время?
2 ответа
Пример преобразован в сопоставление с образцом
Вот эквивалентный код, использующий совпадение и регистр :
match x:
case int():
pass
case str():
x = int(x)
case float() | Decimal():
x = round(x)
case _:
raise TypeError('Unsupported type')
Объяснение
PEP 634 указывает, что проверки isinstance() выполняются с помощью шаблонов классов . Чтобы проверить экземпляр str , напишите
case str(): ...
. Обратите внимание, что скобки важны. Вот как грамматика определяет, что это шаблон класса.
Чтобы проверить несколько классов одновременно, PEP 634 предоставляет шаблон или с помощью
|
оператор. Например, чтобы проверить, является ли объект экземпляром типа float или Decimal, напишите
case float() | Decimal(): ...
. Как и раньше, скобки важны.
Использование питонаmatch
case
Без обработки исключений
match x:
case int():
pass
case str():
x = int(x)
case float() | Decimal():
x = round(x)
case _:
raise TypeError('Unsupported type')
Некоторые дополнения
В этом коде все еще есть несколько потоков.
С обработкой исключений
match x:
case int():
pass
case str():
try:
x = int(x)
except ValueError:
raise TypeError('Unsupported type')
case float() | Decimal():
x = round(x)
case _:
raise TypeError('Unsupported type')
Как функция
def func(x):
match x:
case int():
pass
case str():
try:
x = int(x)
except ValueError:
raise TypeError('Unsupported type')
case float() | Decimal():
x = round(x)
case _:
raise TypeError('Unsupported type')
return x