¿Cuándo se debe establecer un argumento en Ninguno en Python?

Sep 10 2020

El foco de mi pregunta está en el diseño.

Si tengo un argumento que puede ser Noney se pasa entre varias funciones hasta que finalmente se usa, ¿qué función debería tratarlo como un argumento predeterminado?

Por ejemplo, suponga el siguiente bloque de código:

def foo(a):
 b = # some code block to assign b
 return bar(a, b)

def bar(a, b):
 c = # some code block to assign c
 return baz(a, b, c)

def baz(a, b, c):
 return a + b + c

El valor predeterminado debe establecerse solo en fooy todas las demás funciones deben esperar que el argumento sea obligatorio (por ejemplo, foo(a=None); bar(a, b); baz(a, b, c))? ¿O hay un mejor diseño?

Y si fuera necesaria la verificación de tipo, ¿cuál es la función más adecuada para ello?

Respuestas

4 DocBrown Sep 10 2020 at 09:55

Para tomar decisiones sensatas sobre los argumentos predeterminados, es necesario conocer el contexto en el que se van a utilizar estas funciones. .

Si foova a ser parte de la API pública de un módulo o componente, al proporcionar un argumento predeterminado se a=Nonesupone que hay un escenario de uso frecuente en el foo()que se llamará de esta forma, sin ningún parámetro. La misma medida es válida para bary baz:

  • ¿Esas funciones se utilizan "internamente"? Entonces sabrá con precisión si proporcionar un argumento predeterminado le ahorrará algo de código repetitivo, o si bar(a, b)solo se llama una o dos veces, tal vez solo dentro foo, en cuyo caso un argumento predeterminado no es beneficioso

  • ¿O esas funciones también forman parte de la API pública? Luego, debe estimar cómo se verá su escenario de uso típico (para lo cual necesita un contexto real). Si desea proporcionar la capacidad de barser llamado como bar(b="some value"), entonces bar(a=none, b)es necesario proporcionar la firma , independientemente del parámetro predeterminado en foo.

Entonces, para tomar decisiones sobre argumentos predeterminados, no mires el lado de la implementación, ¡mira el lado del uso!

Con respecto a la verificación de tipo: no soy un experto en este tema en Python, pero supongo que si desea agregar anotaciones de tipo para el análisis de tipo estático, en mi humilde opinión, tendrá más sentido agregarlas en cada nivel de la cadena de llamadas (puede ser realmente obligatorio para que el análisis de tipo funcione). Si la "función más interna" ( baz) espera solo argumentos de un cierto tipo, obviamente debe poner las anotaciones de tipo allí. Esto, sin embargo, implica que fooy barsolo funcionará correctamente con argumentos del mismo tipo, lo que significa que para el análisis de tipo estático las anotaciones también son necesarias allí.