working with what used print generators funcion for explicacion are python generator yield

python - with - para x en y(): ¿cómo funciona esto?



what are python generators used for (5)

En Python, la instrucción for le permite iterar sobre los elementos.

Según la documentation :

La instrucción for de Python itera sobre los elementos de cualquier secuencia (una lista o una cadena), en el orden en que aparecen en la secuencia

Aquí, el elemento será el valor de retorno de spinning_cursor() .

Esta pregunta ya tiene una respuesta aquí:

Estaba buscando un código para girar un cursor en el terminal y encontré esto. Me preguntaba qué estaba pasando en el código. En particular for c in spinning_cursor(): nunca he visto esta sintaxis. ¿Es porque estoy devolviendo un elemento de un generador a la vez con yield , y esto se asigna a c? ¿Algún otro ejemplo de esto para x en y () uso?

import sys import time def spinning_cursor(): cursor=''/-/|'' i = 0 while 1: yield cursor[i] i = (i + 1) % len(cursor) for c in spinning_cursor(): sys.stdout.write(c) sys.stdout.flush() time.sleep(0.1) sys.stdout.write(''/b'')


La explicación de Martijn Pieters es excelente. A continuación se muestra otra implementación del mismo código que tenía en la pregunta. utiliza itertools.cycle para producir el mismo resultado que spinning_cursor . itertools está lleno de excelentes ejemplos de iteradores y funciones para ayudar a crear sus propios iteradores. Podría ayudarte a entender mejor a los iteradores.

import sys, time, itertools for c in itertools.cycle(''/-/|''): sys.stdout.write(c) sys.stdout.flush() time.sleep(0.1) sys.stdout.write(''/b'')


La función spinning_cursor devuelve un iterable (un generador de rendimiento).

for c in spinning_cursor():

sería lo mismo que

for i in [1, 2, 3, 4]:


La sintaxis de for c in spinning_cursor() es un bucle for-each bucle. Va a iterar a través de cada elemento en el iterador devuelto por spinning_cursor() .

El interior del bucle:

  1. Escriba el carácter en estándar y vacíe para que se muestre.
  2. Duerme una décima de segundo
  3. Write /b , que se interpreta como un retroceso (elimina el último carácter). Observe que esto sucede al final del bucle, por lo que no se escribirá durante la primera iteración y que comparte la llamada al ras en el paso 1.

spinning_cursor() devolverá un generator , que en realidad no se ejecuta hasta que comienzas a iterar. Parece que pasará por ''/-/|'' , en orden, para siempre. Es como tener una lista infinita para recorrerla.

Por lo tanto, la salida final va a ser un spinner ASCII. Verás estos caracteres (en el mismo lugar) repitiéndose hasta que mates el guión.

/ - / |


Usar el yield convierte una función en un generator . Un generador es un tipo especializado de iterator . for siempre realiza un bucle sobre iterables, tomando cada elemento por turno y asignándolos a los nombres que haya indicado.

spinning_cursor() devuelve un generador, el código dentro de spinning_cursor() no se ejecuta hasta que comienzas a iterar sobre el generador. Iterar sobre un generador significa que el código en la función se ejecuta hasta que se encuentra con una declaración de yield , momento en el que el resultado de la expresión allí se devuelve como el siguiente valor y la ejecución se detiene nuevamente.

El bucle for hace justamente eso, llamará al equivalente de next() en el generador, hasta que el generador StopIteration que se realiza levantando StopIteration (que ocurre cuando la función regresa). Cada valor de retorno de next() se asigna, a su vez, a c .

Puedes ver esto creando el generador en el indicador de Python:

>>> def spinning_cursor(): ... cursor=''/-/|'' ... i = 0 ... while 1: ... yield cursor[i] ... i = (i + 1) % len(cursor) ... >>> sc = spinning_cursor() >>> sc <generator object spinning_cursor at 0x107a55eb0> >>> next(sc) ''/'' >>> next(sc) ''-'' >>> next(sc) ''//' >>> next(sc) ''|''

Este generador específico nunca regresa, por lo que StopIteration nunca se StopIteration y el bucle for continuará para siempre a menos que se elimine la secuencia de comandos.