Reputation: 226221
I want to convert this existing code to use pattern matching:
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')
How do you write isinstance
checks with pattern matching, and how do you test against multiple possible types like (float, Decimal)
at the same time?
Upvotes: 49
Views: 19691
Reputation: 226221
Here's the equivalent code using match and case:
match x:
case int():
pass
case str():
x = int(x)
case float() | Decimal():
x = round(x)
case _:
raise TypeError('Unsupported type')
PEP 634, available since Python 3.10, specifies that isinstance() checks are performed with class patterns. To check for an instance of str, write case str(): ...
. Note that the parentheses are essential. That is how the grammar determines that this is a class pattern.
To check multiple classes at a time, PEP 634 provides an or-pattern using the |
operator. For example, to check whether an object is an instance of float or Decimal, write case float() | Decimal(): ...
. As before, the parentheses are essential.
Upvotes: 67
Reputation: 819
Using python match
case
Without Exception handling
match x:
case int():
pass
case str():
x = int(x)
case float() | Decimal():
x = round(x)
case _:
raise TypeError('Unsupported type')
Some extras
There are still some flows in this code.
With exception handling
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')
As a function
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
Upvotes: 5