(Título y contenido actualizados después de leer la respuesta de Alex)¿Es Pythonic que una función devuelva un iterable o no iterable dependiendo de su entrada?
En general, creo que se considera una mala forma (no pitthonic) para que una función a veces devuelva un elemento iterable y en ocasiones único en función de sus parámetros. Por ejemplo, struct.unpack
siempre devuelve una tupla incluso si contiene solo un elemento.
Estoy tratando de finalizar el API para un módulo y tengo algunas funciones que pueden tener uno o más parámetros (a través de *args
) como este:
a = s.read(10) # reads 10 bits and returns a single item
b, c = s.read(5, 5) # reads 5 bits twice and returns a list of two items.
de modo que devuelve un solo elemento si hay solo un parámetro; de lo contrario, devuelve una lista. Ahora creo que esto está bien y para nada confuso, pero sospecho que otros pueden estar en desacuerdo.
El caso de uso más común para estas funciones sería sólo quieren un único artículo devuelto, por lo que siempre devolviendo una lista (o tupla) se siente mal:
a, = s.read(10) # Prone to bugs when people forget to unpack the object
a = s.read(10)[0] # Ugly and it's not clear only one item is being returned
Otra opción es tener dos funciones:
a = s.read(10)
b, c = s.read_list(5, 5)
lo cual está bien, pero estorba hasta la API y requiere que el usuario recuerde el doble de funciones sin añadir ningún valor.
Así que mi pregunta es: ¿A veces se devuelve un elemento iterable y, a veces un solo elemento confuso y no-Ptónico? Si es así, ¿cuál es la mejor opción?
actualización: Creo que el consenso general es que es muy travieso sólo devuelve un iterable veces. Creo que la mejor opción para la mayoría de los casos sería devolver siempre el iterable, incluso si contenía solo un elemento.
Habiendo dicho eso, en mi caso particular, creo que voy a dividirme en dos funciones (read(item)
/readlist(*items)
), y el razonamiento es que creo que el caso del artículo individual ocurrirá con mucha más frecuencia que el caso del artículo múltiple , por lo que es más fácil de usar y la API cambia menos problemática para los usuarios.
Gracias a todos.
+1. A veces ser una cosa y, a veces ser una lista de cosas suele ser un error. Python lo hizo para% -formatting y esto es ampliamente considerado como un error y una trampa desagradable. – bobince
Temía que la gente dijera esto: ¡se siente mal recibir una lista cuando claramente solo has pedido un artículo! –
@Scot Griffiths: En mi humilde opinión, los posibles errores causados por ser demasiado inteligente superan los problemas que una variable simple podría causar. ¿Por qué no usar un método como'def read (a_tuple): 'en vez de usar' * args'? – voyager