Sök…


Anmärkningar

Det finns INGEN switch-uttalande i python som val av språkdesign. Det har funnits en PEP ( PEP-3103 ) som täcker ämnet som har avvisats.

Du kan hitta många lista med recept på hur du gör dina egna switch-uttalanden i python, och här försöker jag föreslå de mest förnuftiga alternativen. Här är några platser att kolla:

Använd vad språket erbjuder: if / else-konstruktionen.

Tja, om du vill ha en switch / case konstruktion är det enklaste sättet att använda den gamla gamla if / else konstruktionen:

def switch(value):
    if value == 1:
        return "one"
    if value == 2:
        return "two"
    if value == 42:
        return "the answer to the question about life, the universe and everything"
    raise Exception("No case found!")

det kan se överflödigt och inte alltid vackert, men det är överlägset det mest effektiva sättet att gå, och det gör jobbet:

>>> switch(1)
one
>>> switch(2)
two
>>> switch(3)
…
Exception: No case found!
>>> switch(42)
the answer to the question about life the universe and everything

Använd en funktionsdikt

Ett annat enkelt sätt att gå är att skapa en ordbok med funktioner:

switch = {
    1: lambda: 'one',
    2: lambda: 'two',
    42: lambda: 'the answer of life the universe and everything',
}

lägger du till en standardfunktion:

def default_case():
    raise Exception('No case found!')

och du använder ordlistans get-metod för att få funktionen som ges värdet för att kontrollera och köra den. Om värdet inte finns i ordboken default_case .

>>> switch.get(1, default_case)()
one
>>> switch.get(2, default_case)()
two
>>> switch.get(3, default_case)()
…
Exception: No case found!
>>> switch.get(42, default_case)()
the answer of life the universe and everything

du kan också göra lite syntaktiskt socker så att omkopplaren ser trevligare ut:

def run_switch(value):
    return switch.get(value, default_case)()

>>> run_switch(1)
one

Använd klassens introspektion

Du kan använda en klass för att härma omkopplaren / ärendet. Följande använder introspektion av en klass (med getattr() som löser en sträng till en bunden metod i en instans) för att lösa "case" -delen.

Då är introspekteringsmetoden alias till __call__ metoden för att överbelasta operatören () .

class SwitchBase:
    def switch(self, case):
        m = getattr(self, 'case_{}'.format(case), None)
        if not m:
            return self.default
        return m

    __call__ = switch

För att det ska se trevligare ut underklasserar SwitchBase klassen SwitchBase (men det kan göras i en klass), och där definierar vi alla case som metoder:

class CustomSwitcher:
    def case_1(self):
        return 'one'

    def case_2(self):
        return 'two'

    def case_42(self):
        return 'the answer of life, the universe and everything!'

    def default(self):
        raise Exception('Not a case!')

så då kan vi äntligen använda det:

>>> switch = CustomSwitcher()
>>> print(switch(1))
one
>>> print(switch(2))
two
>>> print(switch(3))
…
Exception: Not a case!
>>> print(switch(42))
the answer of life, the universe and everything!

Med hjälp av en context manager

Ett annat sätt, som är mycket läsbart och elegant, men långt mindre effektivt än en om / annars-struktur, är att bygga en klass som följer, som kommer att läsa och lagra värdet att jämföra med, exponera sig själv inom ramen för sammanhanget som kommer att returnera sant om det matchar det lagrade värdet:

class Switch:
    def __init__(self, value): 
        self._val = value
    def __enter__(self):
        return self
    def __exit__(self, type, value, traceback):
        return False # Allows traceback to occur
    def __call__(self, cond, *mconds): 
        return self._val in (cond,)+mconds

att definiera ärendena är nästan en matchning med den verkliga switch / case konstruktionen (utsatt i en funktion nedan, för att göra det lättare att visa upp):

def run_switch(value):
    with Switch(value) as case:
        if case(1):
            return 'one'
        if case(2):
            return 'two'
        if case(3):
            return 'the answer to the question about life, the universe and everything'
        # default
        raise Exception('Not a case!')

Så exekveringen skulle vara:

>>> run_switch(1)
one
>>> run_switch(2)
two
>>> run_switch(3)
…
Exception: Not a case!
>>> run_switch(42)
the answer to the question about life, the universe and everything

Nota Bene :



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow