Python Language
Alternativ för att byta uttalande från andra språk
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 :
- Denna lösning som erbjuds som switch-modulen tillgänglig på pypi .