1. ホーム
  2. python

[解決済み] リターンとイールドを同一機能で表現

2023-03-14 04:53:04

質問

Pythonでyieldとreturnが同じ関数で使われた場合、具体的にどのようなことが起こるのでしょうか?

def find_all(a_str, sub):
    start = 0
    while True:
        start = a_str.find(sub, start)
        if start == -1: return
        yield start
        start += len(sub) # use start += 1 to find overlapping matches

やはり発電機なのでしょうか?

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

はい、やはり発電機です。その return を上げるのと(ほぼ)同じです。 StopIteration .

PEP 255 はそれを綴っています。

<ブロッククオート

仕様です。戻る

ジェネレータ関数は、returnステートメントを含むことができます。

"return"

のreturnステートメントではexpression_listは許されないことに注意してください。 はジェネレータ本体の return 文では許されないことに注意してください。 の本体には現れるかもしれませんが)。

returnステートメントに遭遇した場合、制御はあらゆる 関数のreturnと同様に制御が進み、適切なfinally節があればそれを実行します。 を実行します。) その後、StopIteration例外が発生し、イテレータが使い果たされたことを通知します。 イテレータが使い果たされたことを示します。 StopIteration例外は、以下の場合にも発生します。 制御が明示的な戻り値なしにジェネレータの終端から流れた場合にもStopIteration例外が発生します。

returnは、ジェネレータ関数と非ジェネレータ関数の両方において、"もう終わり、何も面白いものはありません。 ジェネレータ関数と非ジェネレータ関数の両方において、returnは"を意味することに注意してください。

returnは常にStopIterationを発生させることと同じではないことに注意してください。 その違いは、try/except 構成をどのように扱うかにあります。 扱われるかにあります。例えば

>>> def f1():
...     try:
...         return
...     except:
...        yield 1
>>> print list(f1())
[]

なぜなら、どんな関数でもそうですが、returnは単に終了するだけですが

>>> def f2():
...     try:
...         raise StopIteration
...     except:
...         yield 42
>>> print list(f2())
[42]

StopIterationは、他の例外と同様に、素の"except"によって捕捉されるからです。 例外です。