このように、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"
Expression_listは、ジェネレーターの本体のreturnステートメントでは許可されないことに注意してください(もちろん、ジェネレーター内にネストされた非ジェネレーター関数の本体に表示される場合があります)。
Returnステートメントが検出されると、制御は任意の関数returnのように進み、適切なfinally節(存在する場合)を実行します。次に、StopIteration例外が発生し、反復子が使い果たされたことを通知します。 StopIteration例外は、明示的な戻りなしで制御がジェネレーターの端から流れた場合にも発生します。
ジェネレーター関数と非ジェネレーター関数の両方について、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は、例外と同様に、裸の「例外」によってキャプチャされるためです。
はい、それはまだジェネレータです。空のreturn
またはreturn None
を使用して、ジェネレーター関数を終了できます。これは、StopIteration
(詳細は @ NPEの答え を参照)を上げるのと同じです。
None以外の引数での戻り値は、3.3より前のバージョンPythonのSyntaxError
です。
Python 3.3から始まるコメントで@BrenBarnが指摘したように、戻り値はStopIteration.
に渡されるようになりました]
PEP 38 から:
ジェネレーターでは、ステートメント
return value
意味的に等価です
raise StopIteration(value)
値またはジェネレーターを返すことができる関数にyieldおよびreturnメソッドを設定する方法があります。
おそらくあなたが望むほどきれいではありませんが、期待どおりに動作します。
次に例を示します。
def six(how_many=None):
if how_many is None or how_many < 1:
return None # returns value
if how_many == 1:
return 6 # returns value
def iter_func():
for count in range(how_many):
yield 6
return iter_func() # returns generator