1717 Stimmen

Ersetzungen für switch-Anweisung in Python?

Ich möchte eine Funktion in Python schreiben, die je nach dem Wert eines Eingabeindexes verschiedene feste Werte zurückgibt.

In anderen Sprachen würde ich ein switch o case Anweisung, aber Python scheint nicht über eine switch Aussage. Was sind die empfohlenen Python-Lösungen in diesem Szenario?

77 Stimmen

PEP zum Thema, verfasst von Guido selbst: PEP 3103

28 Stimmen

@chb In diesem PEP erwähnt Guido nicht, dass if/elif-Ketten auch eine klassische Fehlerquelle sind. Es ist ein sehr anfälliges Konstrukt.

15 Stimmen

Was bei allen Lösungen fehlt, ist die Erkennung von doppelte Fallwerte . Als Fail-Fast-Prinzip kann dies ein größerer Verlust sein als die Leistung oder die Fallthrough-Funktion.

1voto

sudhir tataraju Punkte 933

Leicht zu merken:

while True:
    try:
        x = int(input("Enter a numerical input: "))
    except:
        print("Invalid input - please enter a Integer!");
    if x==1:
        print("good");
    elif x==2:
        print("bad");
    elif x==3:
        break
    else:
        print ("terrible");

1voto

nrp Punkte 431

Die folgende funktioniert für meine Situation, wenn ich eine einfache Switch-Case benötigen, um eine Reihe von Methoden aufrufen und nicht nur einige Text drucken. Nachdem ich mit Lambda und Globals herumgespielt habe, hat sich das für mich als die einfachste Option herausgestellt. Vielleicht hilft es ja auch jemandem:

def start():
    print("Start")

def stop():
    print("Stop")

def print_help():
    print("Help")

def choose_action(arg):
    return {
        "start": start,
        "stop": stop,
        "help": print_help,
    }.get(arg, print_help)

argument = sys.argv[1].strip()
choose_action(argument)()  # calling a method from the given string

0 Stimmen

Machen Sie Ihre Action-Funktionen zu Closures - d.h. definieren Sie sie in Ihrer choose_action-Funktion - und Sie können auch auf alle Argumente etc. zugreifen :-) d.h. es wird meine Lösung ...

1voto

Harry247 Punkte 21

Verwenden Sie auch die Liste für die Speicherung der Fälle, und rufen Sie die entsprechende Funktion mit select -

cases = ['zero()', 'one()', 'two()', 'three()']

def zero():
  print "method for 0 called..."
def one():
  print "method for 1 called..."
def two():
  print "method for 2 called..."
def three():
  print "method for 3 called..."

i = int(raw_input("Enter choice between 0-3 "))

if(i<=len(cases)):
  exec(cases[i])
else:
  print "wrong choice"

Auch erklärt unter Schraubentisch .

0 Stimmen

Warum sollte man exec verwenden, wenn man Funktionsobjekte in einer Liste und nicht in einer Liste von Strings speichern kann?

0voto

damirlj Punkte 65

Eine switch-Anweisung ist nur syntaktischer Zucker für if/elif/else. Jede Kontrollanweisung delegiert den Auftrag, wenn eine bestimmte Bedingung erfüllt ist - Entscheidungspfad. Um dies in ein Modul zu verpacken und einen Job auf der Grundlage seiner eindeutigen ID aufrufen zu können, kann man die Vererbung und die Tatsache, dass jede Methode in Python virtuell ist, nutzen, um die abgeleitete klassenspezifische Job-Implementierung als einen spezifischen "Fall"-Handler bereitzustellen:

#!/usr/bin/python

import sys

class Case(object):
    """
        Base class which specifies the interface for the "case" handler.
        The all required arbitrary arguments inside "execute" method will be
        provided through the derived class
        specific constructor

        @note in Python, all class methods are virtual
    """
    def __init__(self, id):
        self.id = id

    def pair(self):
        """
            Pairs the given id of the "case" with
            the instance on which "execute" will be called
        """
        return (self.id, self)

    def execute(self): # Base class virtual method that needs to be overridden
        pass

class Case1(Case):
    def __init__(self, id, msg):
        self.id = id
        self.msg = msg
    def execute(self): # Override the base class method
        print("<Case1> id={}, message: \"{}\"".format(str(self.id), self.msg))

class Case2(Case):
    def __init__(self, id, n):
        self.id = id
        self.n = n
    def execute(self): # Override the base class method
        print("<Case2> id={}, n={}.".format(str(self.id), str(self.n)))
        print("\n".join(map(str, range(self.n))))

class Switch(object):
    """
        The class which delegates the jobs
        based on the given job id
    """
    def __init__(self, cases):
        self.cases = cases # dictionary: time complexity for the access operation is 1
    def resolve(self, id):

        try:
            cases[id].execute()
        except KeyError as e:
            print("Given id: {} is wrong!".format(str(id)))

if __name__ == '__main__':

    # Cases
    cases=dict([Case1(0, "switch").pair(), Case2(1, 5).pair()])

    switch = Switch(cases)

    # id will be dynamically specified
    switch.resolve(0)
    switch.resolve(1)
    switch.resolve(2)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X