Los lenguajes de programación como C/C++, C#, Java, JavaScript y Pascal ( Referencia ) tienen una combinación de sentencias switch y case (a veces también llamadas select o inspect ) que le permiten comparar un valor con varias condiciones para realizar ciertas acciones.
my_value = 10; switch(my_value) { case 10: print("The number is ten"); case 2*10: print("The number is the double of ten"); case 100: print("The number is one hundred"); default: print("The number is none of 10, 2*10 or 100"); } Pseudocódigo para representar la sintaxis especial de la construcción switch - case .
Al ser consciente de los equivalentes funcionales como las búsquedas en el diccionario , ¿existe un equivalente puramente sintáctico para la construcción de programación anterior?
A partir de Python 3.10.0 (alpha6 lanzado el 30 de marzo de 2021) , Python tiene un equivalente sintáctico oficial llamado match .
La sintaxis básica es:
match value: case condition: action(s) ... Para versiones anteriores de Python, solo hay soluciones alternativas si no desea recurrir a if - elif - else . Vea esta excelente publicación de la comunidad para ver una colección de algunos.
my_value = 10 match my_value: case 10: print("The number is ten") case 2*10: print("The number is the double of ten") case 100: print("The number is one hundred") case _: # this is the default handler if none # of the above cases match. print("The number is none of 10, 2*10 or 100")Por lo tanto, otras respuestas que involucran soluciones alternativas ya no son válidas, también desde el punto de vista del rendimiento.
Si proviene de idiomas que admiten switch y case , es probable que ya conozca su comportamiento. Sin embargo, con Python, hay algunas diferencias a tener en cuenta.
Los casos no se caen
Es común que los lenguajes con switch - declaraciones de case ejecuten cada caso que coincida con el valor, de arriba a abajo. Por lo tanto, hay una tercera declaración, break , para usar en construcciones de case de switch si no desea fallar:
value = 10 switch (value) { case 10: print("Value is ten"); case 2*5: print("Value is the double of five"); break; case 20/2: print("Value is the half of twenty"); default: print("This is just the default action."); } En este ejemplo, los dos primeros casos se ejecutarían porque el primer caso falla. Si no hubiera una declaración de break dentro del segundo caso, se ejecutarían todos los casos, incluido el predeterminado.
En Python, solo se ejecuta el primer caso coincidente . Puede pensar en ello como si cada caso contuviera una declaración de break oculta.
Las referencias a variables no funcionan como condición.
base_color = "red" chosen_color = "green" match chosen_color: case base_color: print("Yes, it matches!")¡Este código realmente imprime que los colores coinciden!
Las referencias de variables desnudas como condiciones de caso siempre coincidirán.
Independientemente, los literales como case "red": ... y los nombres calificados (es decir, con puntos) como case AllColors.red funcionan como se esperaba, no hay necesidad de tener miedo de ellos.
Todo esto es así, porque Python Software Foundation no decidió simplemente copiar otro aburrido modelo de flujo de control, sino implementar un comparador de patrones completo que es más que una simple declaración de switch de case . Más sobre esto se puede encontrar en la siguiente sección.
match - Match a in ' t case hooey
La especificación y la información proporcionadas en las Propuestas de mejora de Python (PEP) nos. 634-636
En Python, la match es en realidad mucho más que un simple cambio, de ahí probablemente el nombre. Cuenta con una funcionalidad especial como marcadores de posición profundos y comodines.
Ejemplos inspirados en la lectura de la documentación, para que no tenga que hacerlo:
match point: case (0, 0): print("Origin") case (0, y): print("Our current Y position is", y, " now.") Puede hacer coincidir estructuras de datos anidadas arbitrarias, incluidos marcadores de posición. En el ejemplo anterior, estamos emparejando una tupla con dos elementos donde, en el segundo caso, usamos un marcador de posición y que obtiene su valor asignado al emparejar.
También puede hacer coincidir los atributos de clase, de una manera muy similar:
class Point: x: int y: int def location(point): match point: case Point(x=0, y=0): print("Origin is the point's location.") case Point(x=0, y=y): print("The point lies on the y axis at a height of", y, "units.") Esto también explica por qué no puede hacer coincidir las referencias de una sola variable en las condiciones del caso: en realidad no hace coincidir el valor de esa variable, ¡pero en realidad introduce un marcador de posición con ese mismo nombre! Por lo tanto, si fuera a imprimir chosen_color así:
base_color = "red" chosen_color = "green" match chosen_color: case base_color: print("Our base color is", base_color)De hecho, se imprimiría
Nuestro color base es el verde.
porque el base_color ahora es un marcador de posición al que se le asigna el valor de nuestro chosen_color .
Hay muchos más casos de uso para esta coincidencia de patrones avanzada, un par de ellos interesantes mencionados en la documentación de Python .
Tomará su tiempo hasta que Python 3.10 obtenga su merecida adopción. Python 3.10.0 se lanzará de forma estable el 4 de octubre de 2021 , lo que significa que podría incluirse en Ubuntu 22.04 y versiones posteriores.
Si solo quiere jugar y escribir programas por sí mismo, implementarlos en su propio servidor, o si tiene la intención de distribuir sus creaciones en forma de paquete y no como archivos de código fuente simples, pruebe esta nueva función en sus programas: va a ser un beneficio!
Para usuarios de Windows y macOS, esta página presenta las descargas del instalador oficial.
En Debian y Ubuntu, puede usar el muy popular PPA del proyecto "DeadSnakes":
sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.10 python3.10 --versionDocker es una opción para usar Python 3.10 sin pasos de configuración complicados y en un entorno completamente aislado.
docker run -it python:3.10.0a6-alpine
Y eso es. A medida que pasa el tiempo, es posible que se publiquen nuevas versiones alfa o beta. Entonces querrá reemplazar el a6 con una versión diferente .
No hay. Suele hacerse de dos formas, dependiendo del contexto del código:
Usando la sintaxis if/elif puede tener la versión más similar de switch case:
my_value = 10; if my_value == 10: print("The number is ten") elif my_value == 2*10: print("The number is the double of ten") elif my_value == 100: print("The number is one hundred") else: print("The number is none of 10, 2*10 or 100")Otra forma menos común es hacer un dict y asignar a cada condición del interruptor/caso una función correspondiente para llamar:
my_value = 10; def def_action(): print("The number is none of 10, 2*10 or 100") def ten_action(): print("The number is ten") def double_ten_action(): print("The number is ten") def hundred_action(): print("The number is one hundred") { 10: ten_action, 2*10: double_ten_action, 100: hundred_action, }.get( my_value, def_action # This is the final else, if no match if found )()Esto, a pesar de ser menos Pythonic , es útil cuando dentro de los diversos casos tienes mucho código que empeora la legibilidad.