Buscar..


Observaciones

No hay ninguna instrucción de cambio en python como opción de diseño de idioma. Ha habido un PEP ( PEP-3103 ) que cubre el tema que ha sido rechazado.

Puede encontrar muchas listas de recetas sobre cómo hacer sus propias declaraciones de cambio en python, y aquí estoy tratando de sugerir las opciones más sensatas. Aquí hay algunos lugares para comprobar:

Usa lo que el lenguaje ofrece: la construcción if / else.

Bueno, si quieres un constructo de switch / case , la forma más directa de hacerlo es usar el viejo y bueno if / else construye:

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!")

Puede parecer redundante, y no siempre bonito, pero esa es, con diferencia, la forma más eficiente de hacerlo, y hace el trabajo:

>>> 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

Usa un dictado de funciones.

Otra forma directa de hacerlo es crear un diccionario de funciones:

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

a continuación, agrega una función predeterminada:

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

y utiliza el método get del diccionario para obtener la función dado el valor para verificarlo y ejecutarlo. Si el valor no existe en el diccionario, entonces se ejecuta 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

También puedes hacer un poco de azúcar sintáctico para que el interruptor se vea mejor:

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

>>> run_switch(1)
one

Usa la introspección de clase.

Puedes usar una clase para imitar la estructura del conmutador / caso. Lo siguiente es usar la introspección de una clase (usar la función getattr() que resuelve una cadena en un método enlazado en una instancia) para resolver la parte del "caso".

Luego, ese método de introspección se __call__ método __call__ para sobrecargar al operador () .

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

    __call__ = switch

Luego, para que se vea mejor, subclasificamos la clase SwitchBase (pero podría hacerse en una clase), y ahí definimos todos los case como métodos:

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!')

así que finalmente podemos usarlo:

>>> 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!

Usando un administrador de contexto

Otra forma, que es muy legible y elegante, pero mucho menos eficiente que una estructura if / else, es construir una clase como la siguiente, que leerá y almacenará el valor para comparar, exponerse dentro del contexto como un reclamo que devolverá verdadero si coincide con el valor almacenado:

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

luego, definir los casos es casi una coincidencia con el constructo de switch / case real (expuesto dentro de una función a continuación, para que sea más fácil presumir):

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!')

Entonces la ejecución sería:

>>> 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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow