Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert multiple isinstance checks to structural pattern matching

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?

like image 815
Raymond Hettinger Avatar asked Jan 24 '23 09:01

Raymond Hettinger


1 Answers

Example converted to pattern matching

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')

Explanation

PEP 634 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.

like image 186
Raymond Hettinger Avatar answered May 15 '23 14:05

Raymond Hettinger