5

I'm making a pygame game, and whenever I run my code I get the error expected ':'. I am aware that using [ and ] in match/case blocks is used for something else, but how do I get around this issue?

case pygame.KEYDOWN:

    match event.key:

        case game.controls["pan_up"]:
            world_pos[1] -= 1

        case game.controls["pan_left"]:
            world_pos[0] -= 1

        case game.controls["pan_down"]:
            world_pos[1] += 1

        case game.controls["pan_right"]:
            world_pos[0] += 1

Error message box

  • what's `match event.key` used for? – Lei Yang Feb 08 '22 at 13:39
  • When the user presses a key, an event is passed and processed. If this event is a keypress, it is matched to a key in the controls dictionary. For example, if the user pressed `w` (default pan up key), the camera would pan up. – TheAngriestCrusader Feb 08 '22 at 13:44
  • i've never seen such grammer. – Lei Yang Feb 08 '22 at 13:46
  • 2
    @LeiYang this is a new addition in Python 3.10 - [Structural Pattern Matching](https://docs.python.org/3/whatsnew/3.10.html#pep-634-structural-pattern-matching) – shriakhilc Feb 08 '22 at 13:46
  • thanks! good to learn sth. – Lei Yang Feb 08 '22 at 13:48
  • Based on the answers at [How to use values stored in variables as case patterns](https://stackoverflow.com/questions/66159432/how-to-use-values-stored-in-variables-as-case-patterns), it might be better to simply use an if-else block for `event.key`. **This feature is not supposed to be a switch-case**, and so it may not behave as one might expect. I couldn't find anything in the spec that would allow using a value inside a `dict`. Accessing it as `game.controls.get('pan_up')` gives a different error `called match pattern must be a type`. – shriakhilc Feb 08 '22 at 21:58
  • @shriakhilc That's a shame. Thanks anyways! – TheAngriestCrusader Feb 09 '22 at 08:54

1 Answers1

5

1. You can use .get

example based on your code:

case pygame.KEYDOWN:

    match event.key:

        case game.controls.get("pan_up"):
            world_pos[1] -= 1

        case game.controls.get("pan_left"):
            world_pos[0] -= 1

        case game.controls.get("pan_down"):
            world_pos[1] += 1

        case game.controls.get("pan_right"):
            world_pos[0] += 1

2. You can use dotted dict

it is just a subclassed dict that __getattr__ returns self.get.

there is a package for this here and if you are not the one that created that dict you can just cast it like this DottedDict({'bar': 2, 'foo': 1})

ניר
  • 1,204
  • 1
  • 8
  • 28