Python

case-Befehl in Python nachgebaut

In Python gibt es einen Befehl wie case oder switch nicht. Hier ist leider nur ein if-elif-else-Konstrukt möglich, das je nach Umfang schnell unübersichtlich werden kann.
Je nach Anwendungsfall kann man aber den case-Befehl z.B. mit einem dictionary nachbauen.
Die einzelnen Fälle mit der jeweiligen Aktion werden einfach in ein dictionary gepackt. Hierbei macht man sich zu nutze, dass als Wert zu einem Schlüssel auch eine Funktion abgelegt werden kann.

Nehmen wir an, man möchte die Dateigröße je nach Bedarf in einer bestimmten Einheit ausgeben.
Skript-Beispiel: get_file_size.py (Damit das Skript läuft, wird eine Datei beispiel_fuer_case.txt im selben Verzeichnis benötigt.)

#!/usr/bin/env python3

import os
import enum

# Enum für Einheiten
class SIZE_UNIT(enum.Enum):
    BYTES = 1
    KB = 2
    MB = 3
    GB = 4

def berechne_byte(size_in_bytes):
    return size_in_bytes

def berechne_kb(size_in_bytes):
    return size_in_bytes / 1024

def berechne_mb(size_in_bytes):
    return size_in_bytes / (1024 * 1024)

def berechne_gb(size_in_bytes):
    return size_in_bytes / (1024 * 1024 * 1024)

def convert_unit(size_in_bytes, unit):
    """ Konvertiere die Größe von Bytes in andere Einheiten wie KB, MB or GB"""
    sizeunit_dict = {
        SIZE_UNIT.BYTES: berechne_byte,
        SIZE_UNIT.KB: berechne_kb,
        SIZE_UNIT.MB: berechne_mb,
        SIZE_UNIT.GB: berechne_gb
    }
    return sizeunit_dict.get(unit, berechne_byte)(size_in_bytes)

def get_file_size(file_name, size_type=SIZE_UNIT.BYTES):
    """ Hole die Dateigröße in der bestimmten Einheit KB, MB or GB"""
    size = os.path.getsize(file_name)
    return convert_unit(size, size_type)

def main():
    print('*** Ermittle die Dateigröße in verschiedenen Einheiten ***')

    file_path = 'beispiel_fuer_case.txt'

    size = get_file_size(file_path, SIZE_UNIT.BYTES)

    print('Dateigröße in B: ', size)

    size = get_file_size(file_path, SIZE_UNIT.KB)

    print('Dateigröße in KB: ', size)

    size = get_file_size(file_path, SIZE_UNIT.MB)

    print('Dateigröße in MB : ', size)

    size = get_file_size(file_path, SIZE_UNIT.GB)

    print('Dateigröße in GB : ', size)

if __name__ == '__main__':
    main()

Das Herz dieses Skripts ist die Methode „convert_unit“.
Hier würde normalerweise das if-elif-else-Konstrukt auftauchen. Jetzt befindet sich dort ein Dictionary, das die veschiedenen Fälle verarbeiten kann.
Für jede Möglichkeit gibt es einen Eintrag, der durch einen eindeutigen Schlüssel repräsentiert wird. Es wird sinnvollerweise die jeweilige Maßeinheit verwendet. Damit Verwechslungen und Tippfehler vermieden werden, bietet es sich an, ein Enum zu definieren. Somit hat man einen sprechenden Wert beim Aufruf sowie bei der Verarbeitung im Dictionary, den man immer korrekt zuordnen kann.

Beispiel für Aufruf mit Enum:

size = get_file_size(file_path, SIZE_UNIT.BYTES)

Beispiel für Enum im dictionary:

sizeunit_dict = {
        SIZE_UNIT.BYTES: berechne_byte,
        SIZE_UNIT.KB: berechne_kb,
        SIZE_UNIT.MB: berechne_mb,
        SIZE_UNIT.GB: berechne_gb
    }

Jenachdem, mit welcher Einheit (Enum) man die Funktion aufruft, wird dann aus dem Dictionary die passende Aktion geholt, und danach ausgeführt. Hierbei müssen ggfs. die benötigten Parameter übergeben werden.

Beispiel für Verarbeitung:

sizeunit_dict.get(unit, berechne_byte)(size_in_bytes)

In unit befindet sich das Enum, mit dem im Dictionary gesucht wird. Sollte der Wert nicht vorhanden sein, dann kann man beim get-Befehl einen Default-Wert angegben, der zurückgegeben werden soll. Dies verhindert z.B. einen Programmabsturz bei nicht definierten Werten. Die Funktion, die aufgrund des dictionary-Eintrags zurückgegeben wird, kann sofort ausgeführt werden. Im Beispiel benötigt diese Funktion einen Parameter size_in_bytes, der hier mitgegeben wird.