3

Python has the ability to match values against sets of literals or placeholders like this:

choice = "apple"
match choice:
    case "plum": ...
    case "cherry": ...
    case another_fruit:
        print("Your selected fruit is:", another_fruit)

But what if we have a variable called another_fruit and we want to match exactly the value of that variable, instead of assigning a placeholder with the same name? Is there any special syntax for this?

martineau
  • 119,623
  • 25
  • 170
  • 301
kastl
  • 31
  • 3
  • 3
    If you can arrange for the variable to be accessed via a dotted name, such as `fruitmodule.another_fruit`, that would be interpreted as a value rather than a capture variable. Otherwise, the only way I see to do this would be `case f if f==another_fruit:`. – jasonharper Apr 09 '21 at 17:15
  • Ah, the `if` - idea is pretty good. +1 – kastl Apr 09 '21 at 17:16

1 Answers1

3

Option 1

I don't know of a syntactic solution to this. Bare variable names are usually considered placeholders (or to be more correct: "capture patterns").

There is however the rule that qualified (i.e. dotted) names are considered references and not capture patterns. If you stored your variable another_fruit in an object like this:

fruit_object = object()
fruit_object.another_fruit = "peach"

and referenced it like this:

case fruit_object.another_fruit:
    print("It's a peach!")

it will work the way you want.


Option 2

I've also just very recently created a library called match-ref , which allows you to reference any local or global variable via a dotted name:

from matchref import ref

another_fruit = "peach"
choice = "no_peach"

match choice:
    case ref.another_fruit:
        print("You've choosen a peach!")

It does this by making use of Python's inspect module for resolving your local and global namespaces (in this order).


Option 3

Of course, you don't have to install a 3rd-party library if you are ok with losing a little bit of convenience:

class GetAttributeDict(dict):
    def __getattr__(self, name):
        return self[name]

def some_function():
    another_fruit = "peach"
    choice = "no_peach"
    vars = GetAttributeDict(locals())
    
    match choice:
        case vars.another_fruit:
            print("You've choosen a peach!")

The GetAttributeDict makes it possible to access a dictionary using dotted attribute access syntax and locals() is a builtin function to retrieve all variables as a dict in the local namespace.

fameman
  • 3,451
  • 1
  • 19
  • 31
  • Why the [double post](https://stackoverflow.com/a/67106315/6045800)? Your answer there is much more extensive, the question is older and with more answers. This question should have been flagged as duplicate – Tomerikoo Apr 22 '21 at 12:58