7

I have this code to check for whether or not a variable is a number or a Vector2 in my Vector2 class when multiplying.

def __mul__(self, other):
    match type(other):
        case int | float:
            pass
        case Vector2:
            pass

If I run this, I get SyntaxError: name capture 'int' makes remaining patterns unreachable, and when I hover in vscode, it gives me:

"int" is not accessed
Irrefutable pattern allowed only as the last subpattern in an "or" pattern
All subpatterns within an "or" pattern must target the same names
Missing names: "float"
Irrefutable pattern is allowed only for the last case statement

If I remove | float it still won't work, so I can't make them separate cases.

Koviubi56
  • 127
  • 1
  • 7
Zachary Milner
  • 153
  • 1
  • 6
  • you can take hints from this explanation: https://stackabuse.com/python-check-if-variable-is-a-number/ – Pratik Apr 23 '22 at 19:29

2 Answers2

13

Case with a variable (ex: case _: or case other:) needs to be the last case in the list. It matches any value, where the value was not matched by a previous case, and captures that value in the variable.

A type can be used in a case, but implies isinstance(), testing to determine if the value being matched is an instance of that type. Therefore, the value used for the match should be the actual variable other rather than the type type(other), since type(other) is a type whose type would match type().

def __mul__(self, other):
    match other:
        case int() | float():
            pass
        case Vector2():
            pass
charelf
  • 3,103
  • 4
  • 29
  • 51
Rob at TVSeries.com
  • 2,397
  • 1
  • 21
  • 17
  • 1
    This pattern is called a class pattern: "A class pattern provides support for destructuring arbitrary objects". More information can be found in the documentation: https://peps.python.org/pep-0622/#class-patterns – charelf Jan 16 '23 at 14:14
0

Since this is the first result for "How to use match case to check for variable type in python?" this might answer your question as well as many others (Python 3.10+):

def print_type(v):
    match v:
        # None must come before int
        case None:
            print("NONE")
        # bool() must come before int
        case bool():
            print("BOOL")
        case int():
            print("INT")
        case float():
            print("FLOAT")
        case Vector2():
            print("VECTOR2")
        case str():
            print("STR")

Examples:

print_type(1)  # prints INT
a = 1
print_type(a)  # prints INT
print_type(None)  # prints NONE
print_type("Hello")  # prints STR
v = Vector2()
print_type(v)  # prints VECTOR2

Read more about this in the documentation (thanks: @charelf)