pythonswitch-statementpython-3.10isinstancestructural-pattern-matching

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?


Solution

  • 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, 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.