match Python Tutorial Teil 24

Seit ich mich mit Python beschäftige fehlte mir ein Sprachkonstrukt, das ähnlich dem switch aus C/C++ oder Java ist, um eine Verzweigung über mehrere Bedingungen zu erreichen. Mit match ist dies seit der Pythonversion 3.10 möglich.

Python Logo (CC-BY-SA The people from the Tango! project / Wikipedia) /match
Python Logo (CC-BY-SA The people from the Tango! project / Wikipedia)

Unter Debian 12 ist Python 3.11 verfügbar, so dass ich mich auf dem Raspberry Pi 5 mal mit dem neuen Schlüsselwort beschäftigen kann. Ich habe das aber auch einem Raspberry Pi 4 mit Raspberry Pi OS bookworm nachvollziehen können.

Umgebung anlegen

Zunächst lege ich mir eine virtuelle Umgebung an und aktiviere sie:

virtualenv teil24
cd teil24
source bin/activate

Mit python --version überprüfe ich, dass ich eine Python Version größer als 3.10 benutze:

Die Ausgabe zeigt, dass Python in der Version 3.11.2 benutzt wird, dort ist match implementiert.

Fallunterscheidung mit elif

Ich hatte dir schon gezeigt, wie du mit elif Kaskaden mehrere Fälle abfragen kannst. Ich persönlich finde diese Lösung sehr unelegant. Ein kurzes Programm zeigt, was ich meine:

print_tag_elif.py

import sys

def print_wochentag(num):
  if num == 0:
    print('Montag')
  elif num == 1:
    print('Dienstag')
  elif num == 2:
    print('Mittwoch')
  elif num == 3:
    print('Donnerstag')
  elif num == 4:
    print('Freitag')
  elif num == 5:
    print('Samstag')
  elif num == 6:
    print('Sonntag')
  else:
    print('unbekannte Eingabe')

if __name__ == '__main__':
  print_wochentag(int(sys.argv[1]))

Das Programm gibt zu den übergebenen Werten von 0 bis 6 den Namen des dazugehörigen Wochentag aus. Bei einer so überschaubaren Anzahl verschiedener Fälle, ist das noch halbwegs gut lesbar. Stell dir aber mal vor, du hast 100 oder mehr verschiedene Fälle, dann wird die Sache schon etwas komplizierter.

Test des Programms mit elif

Fallunterscheidung mit Integer

Das neue Schlüsselwort match macht es uns etwas einfacher.

print_day_match.py

import sys

num=5

def print_wochentag(num):

 match num:
  case 0:
    print('Montag')
  case 1:
    print('Dienstag')
  case 2:
    print('Mittwoch')
  case 3:
    print('Donnerstag')
  case 4:
    print('Freitag')
  case 5:
    print('Samstag')
  case 6:
    print('Sonntag')
  case _:
    print('unbekannte Eingabe')


if __name__ == '__main__':
  print_wochentag(int(sys.argv[1]))

match vergleicht die übergebene Variable num mit dem Wert an jedem case. Nur der Zweig, bei dem der Wert passt, wird dann ausgeführt. Eine Besonderheit findest du bei case _:, dieses Konstrukt steht meistens am Ende des match und wird ausgeführt wenn alle case Zweige vorher nicht zutreffen.

Die match Variante tut dasselbe wie die mit elif.
Die match Variante tut dasselbe wie die mit elif.

match mit Strings

match arbeitet nicht nur mit Integerwerte sondern kann auch mit Strings entscheiden.

print_name_match_str.py

import sys

def print_wochentag(num):

 match num:
  case '0':
    print('Montag')
  case '1':
    print('Dienstag')
  case '2':
    print('Mittwoch')
  case '3':
    print('Donnerstag')
  case '4':
    print('Freitag')
  case '5':
    print('Samstag')
  case '6':
    print('Sonntag')
  case _:
    print('unbekannte Eingabe')


if __name__ == '__main__':
  print_wochentag(sys.argv[1])

Du siehst, die Umwandlung des Kommdozeilenparameters in einen Integer ist hier weggefallen.

Mehrere Werte in einem case

Du kannst einen case Block auch für mehrere Werte ausführen lassen. Die verschiedenen Werte musst du dann per | trennen.

print_class.py

def print_match(name):
  
  print(f'name={name}')
  match name:
    case 'Lisa'|'Ralph'|'Janey':
      print('zweite Klasse bei Ms. Hoover')
    case 'Bart'|'Milhouse'|'Nelson':
      print('vierte Klasse bei Ms. Krabappel')
    case _:
      print('unbekannt')


print_match('Lisa')
print_match('Milhouse')
print_match('Homer')
Ausgabe von print_class.py
Ausgabe von print_class.py

Fallunterscheidung per Datentyp

Du kannst bei match auch über den Datentyp einer Variable unterscheiden.

print_type.py

#encoding:utf-8

def print_type(value):
    match value:
        case int():
            print('Integer')
        case str():
            print('String')
        case list():
            print('Liste')
        case dict() as d:
            print(f'Dictionary mit {len(d)} Einträgen')
        case _:
            print('unbekannter Datentyp')

print_type(1) #Integer

print_type('The Simpsons') # String

print_type([1, 2, 3]) # Liste

print_type({'a': 1, 'b': 2, 'c': 3}) # Dictionary

print_type(1.0) #float ist nicht implentiert

Dazu schreibst nur die Funktion, die dir normalerweise den Datentyp erzeugen hinter das case

Ausgabe von print_type.py
Ausgabe von print_type.py

Fazit

Das match Statement macht den Pythoncode übersichtlicher und ist vielseitig einsetzbar. Was mir persönlich noch fehlt, ist dass man ganze Listen in das case hineingeben kann.

Wie immer findest du die Dateien im Git-Repo. Im nächsten Teil geht’s um reguläre Ausdrücke.

Schreibe einen Kommentar

Cookie Consent Banner von Real Cookie Banner