¿Existe alguna diferencia entre multimétodo y envío múltiple?

CorePress2024-01-16  9

Me gustaría utilizar la sobrecarga en Python. Sé que no es posible por diseño (Python es un lenguaje de tipado dinámico), hay un hilo bastante bueno aquí sobre este tema. Por eso podría usar algo como envío múltiple (multimétodos). Y estoy pensando en la mejor solución, que implementaría envío múltiple para cualquier función o método de clase. ¿Existe alguna solución que esté incluida de forma nativa en Python?

Usar singledispatch (agregado a Python en 3.4) no es suficiente en mi caso (porque solo se considera el tipo del primer argumento y necesito varios).

También sé que podría usar argumentos de palabras clave (es decir, tener una sola función e impulsar el comportamiento verificando todos los argumentos), pero se vuelve complicado cuando tienes muchos argumentos y combinaciones.complementos.

Hasta ahora, pude encontrar estas dos bibliotecas (no incluidas en la biblioteca estándar de Python):

multimethod: proporciona un decorador para agregar múltiples argumentos a las funciones, se puede usar el mismo estilo de registro que functools.singledispatch, funciona bien con anotaciones, incluso puede trabajar con predicados anotados u ofrece un espacio de nombres multimeta especial para clases. multipledispatch: también proporciona un decorador para el envío de múltiples argumentos, no funciona con anotaciones y no me parece tan potente en comparación con la biblioteca anterior.

El uso básico es el siguiente:

from multimethod import multimethod

@multimethod
def add(x: int, y: int):
    ...

@multimethod
def add(x: str, y: str):
    ...

o

from multipledispatch import dispatch

@dispatch(int, int)
def add(x, y):
    ...

@dispatch(str, str)
def add(x, y):
    ...

Esta funcionalidad parece muy similar.

Tengo principalmente dos preguntas:

¿Una de esas múltiples implementaciones de despacho trae alguna (des)ventaja sobre¿el otro? (Por ejemplo, tipos admitidos, velocidad, rendimiento, limitaciones, ...) Parece comparable, pero no estaba seguro de esto, ya que este último (multipledispatch) parece ser más popular (verificando las estrellas de GitHub) pero menos mantenido (y yo incluso decir menos maduro). ¿Existe alguna otra solución (incluso una que esté incluida en la biblioteca estándar de Python)?

------------------------------------

Mis razones sobre por qué el método múltiple es mucho mejor en comparación con el envío múltiple

Escriba la información que agregamos a la firma del método, no a la firma del decorador. Hacerlo es mucho más intuitivo y limpio. La sugerencia de tipo de método múltiple es la misma que se espera del tipo estáticoe support/mypy. Ahora, las anotaciones tipográficas se están volviendo comunes entre los desarrolladores. Entonces, ¡esto ayuda en ambos sentidos! Las sugerencias de tipo multimétodo son oficialmente las mismas que las sugerencias de tipo mypy Tenga en cuenta que, ya sea mediante métodos múltiples o envío múltiple, parece que solo admiten llamadas a funciones sin palabras clave. Si llama a una función con palabras clave en la llamada, ambas fallan. Esto es decepcionante, pero puede que tengan más motivos para hacerlo. Lea las guías de los módulos respectivos. Hablan de llamadas a funciones basadas en palabras clave, pero no muy claro, en mi opinión. Por lo tanto, algunas veces siento que una simple verificación de tipos en nuestra función resolvería todos los problemas a la vez en lugar de utilizar múltiples métodos o envíos múltiples. Después de todo, quiero una solución de primera clase, ya que las funciones son objetos de primera clase. Como sé, no hay solución en el lenguaje para el polimorfismo./sobrecarga de funciones. Pero los métodos múltiples parecen pitónicos y nativos. Simplemente me gusta. Además, los métodos múltiples también admiten el envío único, aunque nunca sentí la necesidad de ello. Gracias por su pregunta. Ya has respondido. No sabía la diferencia exacta hasta que leí tu pregunta. Y ya has dado la respuesta. Gracias por la pregunta.

2

1

En cuanto a 3, el lenguaje de despacho múltiple más grande que se me ocurre, Julia, también envía solo argumentos posicionales. La razón es la ambigüedad. Ejército de reservaUtilice los métodos f(x: int, y: str): devuelve 1 y f(y: str, x: int): devuelve 2. Puede diferenciarlos por el orden de los argumentos f(1, "one") vs f( "uno", 1), pero las palabras clave abandonan el orden y, por tanto, son ambiguas f(y = "uno", x = 1). La única manera de "arreglar" esto sería obligar al usuario a cumplir con algún orden de nombre de argumento. Corríjame si me equivoco, pero tampoco puedo pensar en un lenguaje estático con sobrecarga de funciones que lo haga para parámetros con nombre.

- BatWannaBe

11 de septiembre de 2021 a las 21:52

1

Gracias porsus puntos, definitivamente estoy de acuerdo con las anotaciones tipográficas. Marcaré su respuesta como aceptada por ahora, ya que realmente parece que no hay otra solución y que el método múltiple es mejor en comparación con la biblioteca de envío múltiple.

-Nerxis

22 de septiembre de 2021 a las 6:08



------------------------------------

Además de la respuesta aceptada, también añadiría...

El paquete multimétodo funciona muy bien con sugerencias de tipo diferido en la firma, mientras que multipledispatch no. Por ejemplo...
@multimethod
def __init__(self, color: "Color"):
    self.hex = color.hex

Esto también funciona con anotaciones de importación de __future__, que hacen lo mismo de forma interna.

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare