I am playing with this new match-case syntax in Python 3.10 and I had a thought whether one would be able to catch exceptions with it. Is it possible?
Let’s take a look!
>>> def say(something):
... match something:
... case "hello":
... print("Hello to you!")
... case TypeError:
... print("Uhm, what was that you said?!")
...
>>> say(123)
Uhm, what was that you said?!
>>> say("hello")
Hello to you!
As you can see, you definitely can! Isn’t Python just amazing? Of course your answer is a resounding yes.
This is a misunderstanding of what’s going on here. Try adding a case something_else: after the case TypeError, which will tell you SyntaxError: name capture 'TypeError' makes remaining patterns unreachable: the case TypeError is not catching a TypeError, it is assigning something to the name TypeError.
The new match/case feature is meant as a cleaner alternative to
lengthy if/elif/else and similar conditional chains. There doesn’t
seem to be any way to reimplement try/except clauses with it, but
those already work somewhat similarly to match/case anyway so I’m
not sure why you’d want to?
To test that x is an instance of TypeError you have to use case TypeError() (note the parentheses).
A name without a dot is interpreted as the assignment target. Case in point: case str: ... will assign x to str, but case builtins.str: ... will perform the equivalent of issubclass(x, str).
Wow, this is very informative for me, thank you very very much! I really appreciate this.
I’m mastering this new match-case syntax and you guys are very supportive here. I am going to use the match-case syntax throught my whole codebase wherever it’s feasible.
May I ask about the as pattern? Where is it syntactically correct to be used: in match and also in case, or just in one of them?
Ha, turns out that in match you can utilize the almighty walrus operator. That’s kinda cool. In case, you can use the as pattern. I always learn something new and it always amazes me.
I don’t see anything to suggest that you can use as with either match
or case, nor do I understand why you would want to. What purpose do you
think as could be used in a match statement?
As @BowlOfRed explained in the example code above, there might be some as pattern use cases that are actually a clean way to implement an algorithm.
In the example, you don’t know which value (either “north”, “south”, “east”, or “west”) the user is going to input, so you bind all of the OR’ed values to a variable (in the example it is direction) and then the value that the direction variable is referencing is processed (whatever the value might happen to be, depends on the user input). A cool trick actually.
I’ve got a new question regarding this new match-case syntax.
How on Earth can I have a syntactically correct case statement that checks for whether the value of the subject is less than 0?
def is_less_than_zero(number):
match number:
case number < 0: # The issue I'm having is here, I can't figure out what is the correct syntax
print("Yes, this number is less than zero.")
case _:
print("No, this number is not less than zero.")
@steven.daprano, you are amazing! Thank you! The first (the top one) example works like a charm! Well, the second (the bottom one) example works as well, but the first one is much cleaner.
So, the solution to my problem is this:
def is_less_than_zero(random_number):
match random_number:
case random_number if random_number < 0:
print("Yes, the number is less than zero.")
case _:
print("No, the number is not less than zero.")
I’m learning so much and I’m very grateful to all of you!
Thank you, @erlendaasland, for your hint. I’m kind of not too keen on the idea of having those if guards. I think they don’t help in readability.
The solution that @steven.daprano gave also adds an if statement to the code, but it’s visually more appealing to me if the if conditional is in the same line as the case expression.
Ah, yes, my bad. I don’t know why I thought the if guard was not in the same line as the case expression. I probably read the second (the bottom one) example that @steven.daprano gave and after reading your comment and reading the tutorial I mixed things up. Sorry 'bout that.