Estoy tratando de entender la nueva sintaxis de coincidencia de patrones estructurales en Python 3.10. Entiendo que es posible hacer coincidir valores literales como este:
def handle(retcode): match retcode: case 200: print('success') case 404: print('not found') case _: print('unknown') handle(404) # not foundSin embargo, si refactorizo y muevo estos valores a variables de nivel de módulo, se produce un error porque las declaraciones ahora representan estructuras o patrones en lugar de valores:
SUCCESS = 200 NOT_FOUND = 404 def handle(retcode): match retcode: case SUCCESS: print('success') case NOT_FOUND: print('not found') case _: print('unknown') handle(404) # File "<ipython-input-2-fa4ae710e263>", line 6 # case SUCCESS: # ^ # SyntaxError: name capture 'SUCCESS' makes remaining patterns unreachable¿Hay alguna forma de usar la declaración de coincidencia para hacer coincidir los valores que se almacenan dentro de las variables?
Si la constante con la que está probando es un nombre con puntos, debe tratarse como una constante en lugar de como el nombre de la variable para colocar la captura (consulte PEP 636 # Coincidencia con constantes y enumeraciones ):
class Codes: SUCCESS = 200 NOT_FOUND = 404 def handle(retcode): match retcode: case Codes.SUCCESS: print('success') case Codes.NOT_FOUND: print('not found') case _: print('unknown') Aunque, dada la forma en que Python está tratando de implementar la coincidencia de patrones , creo que para situaciones como esta, probablemente sea un código más seguro y más claro usar una torre if/elif/else al comparar valores constantes.
Aparte del uso de valores literales , la sección Patrones de valor de PEP 635 menciona el uso de nombres con puntos o el uso de guardias . Vea a continuación para comparar:
valores literales
def handle(code): match code: case 200: print('success') case 404: print('not found') case _: print('unknown')Referencias:
nombres punteados
Cualquier nombre punteado (es decir, acceso de atributo) se interpreta como un patrón de valor.
class StatusCodes: OK = 200 NOT_FOUND = 404 def handle(code): match code: case StatusCodes.OK: print('success') case StatusCodes.NOT_FOUND: print('not found') case _: print('unknown')Referencias:
Guardias
[A] guard es una expresión arbitraria adjunta a un patrón y que debe evaluarse como un valor de "veracidad" para que el patrón tenga éxito.
SUCCESS = 200 NOT_FOUND = 404 def handle(code): match code: case status if status == SUCCESS: print('success') case status if status == NOT_FOUND: print('not found') case _: print('unknown')Referencias:
Espero poder ayudar a arrojar algo de luz sobre por qué los nombres simples funcionan de esta manera aquí.
En primer lugar, como ya han señalado otros, si necesita hacer coincidir los valores como parte de sus patrones, puede hacerlo de la siguiente manera:
Noneif )Me temo que nosotros (los autores de PEP) probablemente cometimos un pequeño error al incluir este fragmento de juguete en uno de los primeros tutoriales... desde entonces se ha vuelto un poco viral. Nuestro objetivo era liderar con el ejemplo más simple posible de coincidencia de patrones, pero en cambio parece que también creamos una primera impresión confusa para muchos (especialmente cuando se repite sin contexto).
La palabra que más se pasa por alto en el título de estos PEP es "estructural". Si no está haciendo coincidir la estructura del tema, la coincidencia de patrones estructurales probablemente no sea la herramienta adecuada para el trabajo.
El diseño de esta función fue impulsado por la desestructuración (como el desempaquetado iterativo en el LHS de las asignaciones, pero generalizado para todos los objetos), por lo que facilitamos mucho la ejecución de la funcionalidad principal de extraer partes de un objeto y vincularlas a nombres También decidimos que sería útil permitir a los programadores hacer coincidir los valores, por lo que los agregamos (con la condición de que cuando se nombran los valores, deben calificarse con un punto, para distinguirlos de las extracciones más comunes ).
La coincidencia de patrones de Python nunca se diseñó realmente con la intención de impulsar declaraciones de cambio de estilo C como esta; eso ha sido propuesto para Python (y rechazado) dos veces antes, así que elegimos ir en una dirección diferente. Además, ya existe una forma obvia de activar un solo valor, que es más simple, más corta y funciona en todas las versiones de Python: ¡una buena escalera if / elif / else !
SUCCESS = 200 NOT_FOUND = 404 def handle(retcode): if retcode == SUCCESS: print('success') elif retcode == NOT_FOUND: print('not found') else: print('unknown') handle(404)(Si está realmente preocupado por el rendimiento o necesita una expresión, enviar desde un diccionario también es una buena alternativa).
python > 3.10 le permite manejar patrones de casos de manera más eficiente.
| y if las declaraciones también se pueden usar.
usando |
match name: case "example_111" | "example_222": return f"Hello {name}" case _: return "Bye" usando la sentencia if
def get_product_info(make, in_dollar): match make: case "product_111" if in_dollar: return "10000 $" case "product_222" if not in_dollar: return "10000*73 INR" case _: return "error"