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
???
???
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With