Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

581
Vistas
¿Cómo usar valores almacenados en variables como patrones de casos?

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 found

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

over 4 years ago · Hanz Gallego
5 Respuestas
Responde la pregunta

0

La match de Python es mucho más que una simple declaración de cambio. Si usa solo lo que considera "nombres de variables", en realidad serán Patrones de captura . según definición en PEP no. 634

Además del hecho de que probablemente no debería usar la match para su caso de uso, debe usar nombres calificados (con puntos) de una de las siguientes maneras:

#1 objeto plano

 statuses = object() statuses.success = 200 status.not_found = 404 def handle(retcode): match retcode: case statuses.success: print("Success") case statuses.not_found: print("Not found")

#2 Programación Orientada a Objetos

 class StatusValues: success = 200 not_found = 404 def handle(retcode): match retcode: case StatusValues.success: print("Success") case StatusValues.not_found: print("Not found")

#3 Acceso simple calificado locals()/globals()

Desarrollé la biblioteca match-ref que le permite acceder a cualquier variable local o global dentro o fuera de cualquier función, simplemente usando el ref. prefijo.

 from matchref import ref import random SUCCESS = 200 NOT_FOUND = 404 def handle(retcode): random_code = random.randint(600,699) match retcode: case ref.SUCCESS: print("Success") case ref.NOT_FOUND: print("Not found") case ref.random_code: print("OK, you win!")

Como puede ver, ref resolvió automáticamente las variables de sus espacios de nombres locales y globales (en este orden). No es necesaria ninguna configuración adicional.

Si no desea utilizar bibliotecas de terceros, puede ver una versión sin bibliotecas ligeramente similar a continuación.

#4 Acceso calificado locals()/globals() sin librerías de terceros

locals() y globals() son funciones integradas en Python que devuelven un dict que contiene todos los nombres de variables asignados a sus respectivos valores. Debe poder acceder a los valores del dict utilizando la sintaxis punteada, ya que la match tampoco es compatible con la sintaxis de acceso al diccionario. Por lo tanto, puede escribir esta clase de ayuda simple:

 class GetAttributeDict(dict): def __getattr__(self, name): return self[name]

y usarlo así:

 import random SUCCESS = 200 NOT_FOUND = 404 def handle(retcode): random_code = random.randint(600, 699) globs = GetAttributeDict(globals()) locs = GetAttributeDict(locals()) match retcode: case globs.SUCCESS: print("Success") case globs.NOT_FOUND: print("Not found") case locs.random_code: print("OK , you win!")

#5 Acceso al módulo

Dado que parece tener la intención de reutilizar sus códigos de estado (porque de lo contrario podría alinearlos en sus case ), podría considerar usar módulos separados para esto.

constants.py:

 SUCCESS = 200 NOT_FOUND = 404

main.py

 import constants match retcode: case constants.SUCCESS: ... ...

Una vez más, es posible que desee reconsiderar si desea utilizar la match en absoluto.

over 4 years ago · Hanz Gallego Denunciar

0

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"
over 4 years ago · Hanz Gallego Denunciar

0

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.

over 4 years ago · Hanz Gallego Denunciar

0

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:

  • https://www.python.org/dev/peps/pep-0635/#patrones-literales
  • https://www.python.org/dev/peps/pep-0636/#matching-specific-values

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:

  • https://www.python.org/dev/peps/pep-0635/#value-patterns
  • https://www.python.org/dev/peps/pep-0636/#matching-against-constants-and-enums

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:

  • https://www.python.org/dev/peps/pep-0635/#guardias
  • https://www.python.org/dev/peps/pep-0636/#adding-conditions-to-patterns
over 4 years ago · Hanz Gallego Denunciar

0

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:

  • Coincidencia de literales admitidos, como números, cadenas, booleanos y None
  • Coincidencia de nombres calificados (con puntos)
  • Usando pruebas adicionales en guardias (que están separadas de patrones por if )

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 se basó en 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).

over 4 years ago · Hanz Gallego Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda