1. ホーム
  2. python

[解決済み] for x in y(): これはどのように動作するのでしょうか?重複

2023-06-04 10:03:58

質問

ターミナルでカーソルを回転させるコードを探していて、これを見つけました。私はこのコードで何が起こっているのか不思議に思っていました。特に for c in spinning_cursor(): この構文は見たことがありません。私がジェネレータから一度に1つの要素を返すために yield で、これがcに代入されるからでしょうか?y()使用のxのためのこれの他の例はあるか。

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')

どのように解決するのですか?

使用方法 yield を使うと、関数を ジェネレータ . ジェネレータは イテレータ . for は常にイテレータブルをループし、順番に各要素を取り、リストされた名前にそれを割り当てます。

spinning_cursor() はジェネレータを返し、その中のコードは spinning_cursor() の中のコードは、ジェネレータに対する反復処理を開始するまで実際には実行されません。ジェネレータを繰り返し実行するということは、関数内のコードが yield 文に出会うまで実行され、そこで式の結果が次の値として返され、実行は再び一時停止されます。

for ループはまさにこれを行います。 next() をジェネレータ上で呼び出します。 StopIteration を上げることで終了を知らせるまで(関数が戻ったときに起こります)。の各戻り値は next() のそれぞれの戻り値は、順番に c .

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)
'|'

この特定のジェネレータは決して返さないので StopIteration が発生することはなく for のループはスクリプトを終了させない限り永遠に続くでしょう。

より退屈な(しかしより効率的な)代替案としては itertools.cycle() :

from itertools import cycle

spinning_cursor = cycle('/-\|')