¿Existe algún estilo de codificación recomendado / generalmente aceptado para manejar situaciones en las que una función devuelve una tupla de valores pero solo se usa uno de esos valores después (tenga en cuenta que esto está destinado principalmente a las funciones de biblioteca que no puedo cambiar: escribir un contenedor alrededor la llamada es probablemente un poco exagerada ...)? En lugar de hacer
a, b, c = foo()
y luego simplemente no usa b
y c
, ¿cuál de las siguientes variantes debería preferirse (o hay otra?):
Variante 1 (guión bajo)
a, _, _ = foo()
(que es muy claro y simple, pero podría chocar con el _ = gettext.gettext
utilizado en muchas aplicaciones que usan traducción)
Variante 2 (nombre ficticio)
a, unused, unused = foo()
(No muy atractivo, creo, lo mismo ocurre con otros nombres como dummy
)
Variante 3 (índice)
a = foo()[0]
(para mí las ()[0]
miradas no pitónicas ...)
python
coding-style
usuario49643
fuente
fuente
a, b = foo()[0:2]
funcionaría? En caso afirmativo: sí, lo hace :)a, *_ = foo()
desechará todos los valores excepto el primero.Respuestas:
Usar el guión bajo para las variables no utilizadas es definitivamente aceptable. Sin embargo, tenga en cuenta que en algunas bases de código no es una opción, ya que ese identificador está reservado como abreviatura
gettext
. Esta es la objeción más frecuente a este estilo (aunque, por lo que puedo juzgar, no es un problema para la mayoría). Todavía lo recomiendo, y siempre lo uso yo mismo.Los nombres me gustan
dummy
ounused
tienden a irritarme personalmente, y no los veo con demasiada frecuencia (en Python, es decir, conozco una base de código de Delphi que se usadummy
generosamente, y también se ha filtrado en los scripts asociados con el programa en cuestión). Te aconsejaría que no lo hagas.Simplemente extraer un artículo de la tupla devuelta también está bien. También ahorra algunos problemas al obtener la cantidad correcta de valores no utilizados. Sin embargo, tenga en cuenta que tiene dos desventajas potenciales:
fuente
Pylint me ha acostumbrado a hacerlo de esta manera:
Es decir, los resultados no utilizados tienen un nombre descriptivo con el prefijo _. Pylint considera los locales con el prefijo _ como no utilizados, y los globales o atributos con el prefijo _ como privados.
fuente
Si en todo su proyecto, solo está haciendo esto una vez o muy raramente con la función particular, usaría la Variante 1 si sabe
gettext
que no es un problema en ese módulo, y de lo contrario, la Variante 3.Por otro lado, si estaba haciendo esto mucho, y especialmente si cada vez que desea un subconjunto diferente de los valores de retorno (haciendo que un contenedor solo devuelva los que le importan inviables), podría ser beneficioso escribir un contenedor eso pone los resultados en una tupla con nombre , o una instancia de alguna otra clase descriptiva, que le permitiría hacer:
Y luego trabajar con
bar.a
,bar.b
ybar.c
.fuente
Como otros han dicho, subrayar (
_
) es el estándar. Pero si el subrayado se usa para las traducciones, creo que el doble subrayado es la mejor alternativa.var, __, value = "VAR=value".partition('=')
Mejor que estos:
var, unused, value = "VAR=value".partition('=')
var, unused_del, value = "VAR=value".partition('=')
var, _del, value = "VAR=value".partition('=')
fuente
Soy un programador que no es Python, pero para mí la tercera variante tiene más sentido.
En la variante 3, tiene absolutamente claro qué valores le interesa tratar. En las variantes 1 y 2, está asignando los valores a las variables y, por lo tanto, se pueden usar. Es posible que los haya nombrado oscuramente, pero una mala denominación no es realmente una solución a ningún problema.
Además de la claridad, ¿por qué desearía asignar valores no utilizados a una ranura en la memoria (como en las variantes 1 y 2)? Esta sería una solución pobre en términos de administración de memoria.
fuente
Aquí hay una regla general: si solo se usa 1 de los valores devueltos, ¿por qué no simplemente devolver ese 1 valor? En caso de que se llame a la bandera desde varios lugares, mantenga una bandera para el mismo y devuelva los valores según la bandera.
EDITAR:
En caso de que estuviera en su situación y no hubiera escrito la función, tal vez optaría por la Variante 2. Mantendría los nombres ficticios allí para que los parámetros se puedan usar en caso de necesidad. Cortar una lista tendrá un poco de sobrecarga. Quizás pueda ahorrar algunos bytes para recibir los datos no deseados.
fuente
%timeit a, _, _ = foo()
vs.%timeit a = foo()[0]
que resultó en 123ns vs. 109ns, es decir, el corte parece ser realmente más rápido que el desempaquetado de valor. ¿O tenía alguna situación específica en mente?