pequeña redundancia de código dentro mientras que los bucles (no se siente limpio)
-
05-10-2019 - |
Pregunta
Por lo tanto, en Python (aunque creo que se puede aplicar a muchos idiomas), me encuentro con algo como esto con bastante frecuencia:
the_input = raw_input("what to print?\n")
while the_input != "quit":
print the_input
the_input = raw_input("what to print?\n")
Tal vez estoy siendo demasiado exigente, pero eso no me gusta la forma en la the_input = raw_input("what to print?\n")
línea tiene que se repiten. Disminuye la mantenibilidad y la organización. Pero no veo soluciones provisionales para evitar el código duplicado sin empeorar aún más el problema. En algunos idiomas, podría escribir algo como esto:
while ((the_input=raw_input("what to print?\n")) != "quit") {
print the_input
}
Esto es definitivamente no Pythonic, y Python no permite ni siquiera para la asignación dentro de las condiciones de bucle que yo sepa.
Este válidos los arreglos de código de la redundancia,
while 1:
the_input = raw_input("what to print?\n")
if the_input == "quit":
break
print the_input
Pero no se siente del todo bien tampoco. El while 1
implica que este bucle se ejecutará siempre; Estoy usando un bucle, pero dándole una condición falsa y poner el real dentro de él.
Estoy siendo demasiado exigente? ¿Hay una mejor manera de hacer esto? Tal vez hay algo de construcción del lenguaje diseñado para esto que yo no conozco?
Solución
Think iteradores - por ejemplo, en este caso específico:
for the_input in iter(lambda: raw_input('what to print?\n'), 'quit'):
print the_input
La mayoría de los bucles en Python, excepto en los niveles muy bajos de abstracciones, se implementan mejor como bucles for
con la ayuda de algunos subrayando iterador que captura la "lógica de bucle" - el iter
ayuda integrada lata (como aquí) , a veces genexps (expresiones generador) puede, a veces, el itertools
módulo de la biblioteca estándar viene al rescate.
Lo más a menudo que se elija a la costumbre de código funciones del generador (que utilizan yield
), o más de vez en cuando (cuando se necesita realmente sofisticada gestión estatal) una costumbre iterador clase ( uno que define el método especial __iter__
como return self
, y next
[[o __next__
en las últimas versiones de Python]] para volver "el siguiente valor de la iteración).
La captura de la lógica de bucle, aparte de lo que sea que lo sobre los diferentes puntos producidos de forma secuencial por el bucle en sí mismo es la clave de la abstracción-helper aquí!