Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use match case with a class type

I want to use match to determine an action to perform based on a class type. I cannot seem to figure out how to do it. I know their are other ways of achieving this, I would just like to know can it be done this way. I am not looking for workarounds of which there are many.


class aaa():
    pass

class bbb():
    pass

def f1(typ):
    if typ is aaa:
        print("aaa")
    elif typ is bbb:
        print("bbb")
    else:
        print("???")

def f2(typ):
    match typ:
        case aaa():
            print("aaa")
        case bbb():
            print("bbb")
        case _:
            print("???")

f1(aaa)
f1(bbb)
f2(aaa)
f2(bbb)

The output is as follows:

aaa
bbb
???
???
like image 650
pauleohare Avatar asked Dec 05 '25 10:12

pauleohare


1 Answers

You want to match against a constant value. That's a case for constant value patterns:

match typ:
    case somemodule.ClassOne:
        ...
    case anothermodule.ClassTwo:
        ...

Constant value patterns must be of the form NAME ('.' NAME)+ - that is, a name followed by at least one attribute lookup. A bare name will be considered a capture pattern. That's fine for classes defined in other modules, but if you want to match against classes in the same module, you can import the current module:

# in somemodule.py
import somemodule

class ClassOne:
    ...
class ClassTwo:
    ...

match typ:
    case somemodule.ClassOne:
        ...
    case somemodule.ClassTwo:
...

or if you want to avoid the circular import, you can create a namespace:

import types

options = types.SimpleNamespace()
options.ClassOne = ClassOne
options.ClassTwo = ClassTwo

match typ:
    case options.ClassOne:
        ...
    case options.ClassTwo:
        ...

Note that if you go the "import the current module" route, you need to be aware of Python's weird thing where the entry point script is considered the __main__ module, regardless of its file name. If you do python somefile.py and try to import somefile inside that, it will perform a second run of somefile.py as the somefile module and create a second copy of all your classes, and your match statements won't work.

like image 199
user2357112 supports Monica Avatar answered Dec 07 '25 01:12

user2357112 supports Monica