While learning pattern matching introduced in Python 10 I came across an example where a part of splitted string was being assigned/bound to a variable used in one of the cases.
match 'make dir'.split():
case ["make"]:
print("default make")
case ["make", cmd]:
print(f"make command found: {cmd}"}
case ["restart"]:
print("restarting")
case ["rm", *files]:
print (f"deleting files: {files}")
case _:
print("didn't match")
The second case has the previously undeclared variable cmd
, which ends up being assigned the value "dir"
.
In the pattern ["make", cmd]
, cmd
is a capture pattern. Capture patterns (which look like un-dotted names such as foo
, bar
, or cmd
) match anything, and unconditionally bind the matched value to that name.
In your example, any sequence of length 2 starting with "make"
will bind the second element to cmd
and execute the second case
block. This is useful since it allows your app to easily determine which make
command it should execute.
This happens whether cmd
is already assigned or not. So, if it is already bound, that old value will be overwritten with the new, matched value.
If you want to compare a name by value instead, you have a couple of options depending on your situation:
If the name is dotted (like args.cmd
or Class.VAR
), it will automatically compare by equality (and not capture). So you can just use ["make", args.cmd]
as your pattern.
If the name is bare (like cmd
or VAR
), you can use a capture pattern together with a guard to compare by equality. Using this technique, your pattern could look like ["make", c] if c == cmd
. Note that since c
is a capture pattern, it will be rebound just like cmd
in your original example! (As you use pattern matching more, you'll find that capture patterns like c
are extremely useful when performing more complex pattern matches.)
I recommend that anybody looking to familiarize themselves with Python's structural pattern matching check out the official tutorial. It covers all of the different patterns (including capture patterns) in a very easy-to-understand way.