Python_returnとyieldの使い分け #380
Pythonにおいて、returnとyieldはどちらも関数やメソッドから値を返すためにされます。returnは一般的かと思いますが、今回yieldに触れる機会があったのでそれぞれ整理したいと思います。
return
returnは関数から値を返すための標準的な方法です。returnステートメントは、関数の実行を終了し、指定した値を呼び出し元に返します。一度returnステートメントが実行されると、その後の関数のコードは実行されず、関数の制御は呼び出し元に戻ります。
yield
yieldは「生産する」という意味を持つ単語で、Pythonにおいてジェネレータ関数の一部として使われます。ジェネレータ関数とは、その名の通りジェネレータオブジェクトを返す関数で、ジェネレータとは複数の要素を反復して取り出せるオブジェクトです。これはリストやタプルと同様にイテラブルで、 for 文の in の後に置くことができます。
具体的には例えば以下のようなジェネレータ関数を定義できます。
def animal_generator(): # ジェネレータ関数の定義
yield 'dog' # 1つ目の要素を返す
yield 'cat' # 2つ目の要素を返す
yield 'mouse' # 3つ目の要素を返す
yieldは要素を反復して取り出す時に上から順に実行されます。returnは一度返したら終わりですが、yieldは反復して値を返すことが可能です。
ただこれだけだと、例えば以下のようなリストやタプルと何が違うのかよく分かりません。実際に動作自体は同じようなものです。
animals = ['dog', 'cat', 'mouse']
animals = ('dog', 'cat', 'mouse')
最大の違いは、リストやタプルだと「'dog', 'cat', 'mouse'」の全てがメモリに乗りますが、ジェネレータは呼び出された時に呼び出された要素のみが初めてメモリに乗ります。
for文で例を示します。
# listの場合は配列の要素全てがメモリに乗る
for animal in animals:
~ 何かの処理 ~
# ジェネレータの場合は'dog'の番では'dog'だけがメモリに乗る
for animal in animal_generator:
~ 何かの処理 ~
これはデータ一つ一つの容量が大きい時など、パフォーマンスに大きな影響を与えます。animalsでメモリをたくさん占有してしまう状況で、for内の処理に時間がかかったりすると、予期せぬサーバーダウン等につながってしまうかもなので。
ここまでお読みいただきありがとうございました!