Está en la página 1de 6

¿Qué es Structural Pattern Matching de Python y por qué

todos hablan…
paradigmadigital.com/dev/que-es-structural-pattern-matching-python

Hi! Here some our recommendations to get the best out of BLACKBOX:

Be as clear as possible

End the question in what language you want the answer to be, e.g: ‘connect to mongodb in
python

or you can just

Go to Blackbox
Here are some suggestion (choose one):

Write a function that reads data from a json file

1/6
How to delete docs from mongodb in phyton

Connect to mongodb in nodejs

Blackbox AI Chat is in beta and Blackbox is not liable for the content generated. By using
Blackbox, you acknowledge that you agree to agree to Blackbox's Terms and Privacy Policy
Este octubre de 2021 está previsto que se libere la próxima versión del intérprete de
Python. Se trata de la versión 3.10, que traerá varias novedades interesantes. Podemos
ver el roadmap y los principales cambios previstos en el PEP 619.

Sin embargo, de todas las novedades hay una que destaca por ser una de las más
esperadas y que lleva mucho tiempo en discusión dentro del equipo de desarrolladores del
core de Python. Se trata de la característica de Structural Pattern Matching, que ha sido
impulsada personalmente por Guido Van Rossum, el creador original del lenguaje y que, sin
duda, va a dar mucho que hablar.

En este artículo vamos a analizar en qué consiste esta nueva posibilidad que nos ofrece
Python e ilustrarlo con algunos ejemplos.

¿De qué se trata?


Pero, ¿qué es realmente el Structural Pattern Matching? Para hacernos una idea podemos
pensar en una estructura de tipo switch al estilo de las que tenemos en C, Java u otros
lenguajes, pero mucho más potente. Realmente la aproximación más cercana sería la
estructura match, presente en el lenguaje Rust.

Para construir nuestra estructura en Python haremos uso de dos nuevas palabras en el
lenguaje: match y case. Vemos un ejemplo básico para matching de códigos de error HTTP:

def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the Internet"

Vemos como con “match” definimos sobre qué variable queremos hacer la comparación y
con “case” vamos definiendo las posibles alternativas de forma similar a un “switch” clásico.
Anteriormente esto podría implementarse en Python con una secuencia de

2/6
“if..elif..else” pero de este modo queda más elegante. Destacar que “_” actúa como
“wildcard” o comodín para encajar con cualquier expresión que no encaje con el resto de
opciones.

Más madera
Hasta aquí hemos visto un ejemplo básico, que no parece especialmente novedoso. Sin
embargo, las posibilidades son mucho mayores y más potentes para poder hacer matching
con diferentes estructuras y tipos de datos, lo que realmente convierte al “Structural Pattern
Matching” en una herramienta muy conveniente en muchas circunstancias. Vemos algunos
ejemplos más avanzados:

match my_list:
case []:
print("Lista vacía")
case [x]:
print(f"Lista de un elemento: {x}")
case [1, 2] | [2, 1] | [1, 3] | [3, 1]:
print(f"Estas combinaciones me interesan mucho")
case [x, y]:
print(f"Lista con dos elementos: {x} y {y}")
case [x, y, z]:
print(f"Lista con tres elementos: {x}, {y} y {z}")
case [0, 1, 1, 2, *tail]:
print(f"Parece que es la serie de Fibonacci...")
case ["end", "of", "game"]:
print(f"Se acabó el juego...")
case [x, y, *tail]:
print(f"Lista con más de tres elementos. Los dos primeros son: {x} y {y}")

En este ejemplo vemos como junto al case, podemos no solo poner literales o enteros, sino
listas con diferente estructura. De esta forma podemos hacer un manejo muy cómodo y
sencillo en función de la estructura y contenido de la lista recibida y ejecutar diferente lógica,
sin la necesidad de usar la función len() ni acceder explícitamente a los elementos de la
lista.

Como vemos en el tercer “case”, podemos usar el operador “|”, (OR) para declarar varias
opciones que harían match en ese caso.

Con diccionarios también


Podemos operar de forma similar con diccionarios, jugando con su estructura y contenido:

3/6
match customer_data:
case {"password": password, **personal_data}:
customer.set_password(password=password)
customer.update_personal_data(personal_data)
case {"gdpr_check": True, "customer_id": cid}:
apply_gdpr_policies(cid)
case dict(x) if not x:
raise Exception("no data to process")

En este ejemplo vemos diferentes casuísticas: en el primer case estamos verificando la


presencia de una clave en concreto en el diccionario; en el segundo case, de una clave y un
valor específicos; y en el tercero, si se trata de un diccionario vacío.

Este escenario de procesamiento condicionado al contenido de los diccionarios es muy


habitual en muchas ocasiones, por ejemplo cuando procesamos documentos JSON,
formularios o el contenido de peticiones HTTP. De esta forma podemos escribir estos
matchings de una forma más sencilla, elegante y legible.

Incluso con nuestros propios objetos


No sólo podemos hacer uso de tipos de datos básicos de Python, sino que podemos
“matchear” con objetos de clases definidas por nosotros mismos y ahorrarnos un montón de
llamadas a la función isinstance().

match event.get():
case Click(position=(x, y)):
handle_click_at(x, y)
case KeyPress(key_name="Q") | Quit():
game.quit()
case KeyPress(key_name="up arrow"):
game.go_north()
...
case KeyPress():
pass # Ignore other keystrokes
case other_event:
raise ValueError(f"Unrecognized event: {other_event}")

Para ello, en el case declararemos la construcción del objeto con los argumentos
correspondientes nombrados y de esta forma haremos matching.

También es posible no nombrar los argumentos del constructor y pasarlos de forma


posicional, pero para ello tendremos que apoyarnos en el decorador dataclass de la
biblioteca estándar de Python o definiendo el atributo match_args de cualquiera de
nuestras clases:

4/6
from dataclasses import dataclass

@dataclass
class Pair:
first: int
second: int

pair = Pair(10, 20)


match pair:
case Pair(0, x):
print("Case #1")
case Pair(x, y) if x == y:
print("Case #2")
case Pair(first=x, second=20):
print("Case #3")
case Pair as p:
print("Case #4")

En este último ejemplo observamos también la posibilidad de añadir “guardas” o


condicionales adicionales al matching. En el caso 2 vemos cómo se ha añadido una
condición adicional y es que x sea igual a y a través de una construcción “if”. Esto nos
permite llegar a un nivel de casuísticas y de control muy fino.

Conclusión
En resumen, la funcionalidad de Structural Pattern Matching enriquece y mejora un lenguaje
como Python que está vivo y en constante evolución. Al tratarse de un cambio tan
significativo, su desarrollo no ha estado exento de cierta polémica y ha contado con
defensores y detractores, como podemos ver en algunos hilos y conversaciones de foros y
listas de correo.

En cualquier caso, será la comunidad de usuarios de Python la que con el tiempo y la


experiencia, juzgarán los beneficios de esta funcionalidad e iremos viendo si extiende su
uso de forma masiva.

¿Estás deseando tener disponible Python 3.10 para probarlo? No te preocupes, Guido nos
ha dejado un pequeño regalo en este entorno donde ya puedes probar las nuevas
funcionalidades de Python 3.10 en un notebook de Jupyter. Os invito a que juguéis con
Structural Pattern Matching y, por supuesto, que a partir de otoño de 2021 uséis Python 3.10
en vuestros proyectos.

Si quieres profundizar más y entender en profundidad todas las posibilidades del Structural
Pattern Matching, tenemos disponibles tres PEPs (Python Enhancement Proposal) muy
completos con todos los detalles:

Y tú, ¿qué opinión tienes del Structural Pattern Matching?, ¿estás deseando usarlo en
producción o no piensas usarlo nunca? Deja un comentario con tu opinión.

5/6
Manuel Zaforas

Soy Ingeniero Superior en Informática por la UPM. Actualmente trabajo en Paradigma como
líder técnico en el área de innovación en AI y Data

Ver más contenido de Manuel.

Más contenido sobre esto.


Leer más.

Cuéntanos qué te parece.

Los comentarios serán moderados. Serán visibles si aportan un argumento constructivo. Si


no estás de acuerdo con algún punto, por favor, muestra tus opiniones de manera educada.

Suscríbete
Estamos comprometidos.

Tecnología, personas e impacto positivo.

Usamos cookies propias y de terceros con fines analíticos y de personalización. Las puedes
activar, configurar o rechazar. Configurar o rechazar.

6/6

También podría gustarte