ジェネレーターは特別な反復子であり、その中には __iter__
メソッドと __next__
メソッドも含まれています。場合によっては、ループを終了するために StopIteration
例外がスローされることがありますが、イテレーターと比較して、ジェネレーターには「中間値」を保存する機能もあります。次回実行するときにも、この「中間値」を操作します。ジェネレーターのキーワードは yield
です。以下に最も単純なジェネレーターを書いてみましょう。
#!/usr/bin/env python def printNums(): i = 0 while i<10: yield i i = i + 1 def main(): for i in printNums(): print(i) if __name__ == '__main__': main()
パッとコードを見ると「何これ?」と思うかもしれませんが、yield## を使わずに
range を使って生成してみてはいかがでしょうか#? ああ、心配しないでください。ジェネレーターがなぜ必要なのか、またはジェネレーターがどのような問題を解決するのかを見ていきましょう。
python の
memory_profiler モジュールを使用して、プログラム メモリの占有を検出できます。
memory_profilerライブラリ:
pip3 install memory_profiler
@profile デコレータを追加するだけです。例:
@profile def main(): pass
.dat file
mprof runExportアイコンを使用すると、
mprof plot --output=filenamepython case code次の 2 つのプログラムはどちらも 0 ~ 9999999 のデータを出力します。違いは、最初のプログラムでは
range を使用してから
append into
list を使用するのに対し、2 番目のプログラムでは反復子を使用してデータを生成することです。
main.pyプログラム
@profile def main(): data = list(range(10000000)) for i in data: pass if __name__ == '__main__': main()
main_2.pyプログラム
def printNum(): i = 0 while i < 10000000: yield i i = i + 1 @profile def main(): for i in printNum(): pass if __name__ == '__main__': main()
main.py 実行メモリ グラフ
main_2.py 実行メモリ グラフ
yield ステートメントには、
python 解釈権の内部機構が含まれるため、ソース コードを参照することが困難です。その原理を理解するのは困難ですが、
yield の一時停止メカニズムを使用してジェネレーターを探索することができます。
def testGenerator(): print("进入生成器") yield "pdudo" print("第一次输出") yield "juejin" print("第二次输出") def main(): xx = testGenerator() print(next(xx)) print(next(xx)) if __name__ == '__main__': main()
が yield
ステートメントに遭遇すると、現在の関数の実行ステータスが記録され、実行が一時停止され、結果がスローされます。 __next__
メソッドの次の呼び出しを待ち続けます。このメソッドが呼び出された後、関数は次の yield
ステートメントまたは関数の終了まで実行を再開します。 ##関数が実行可能になると、ジェネレーターの終了をマークするために StopIteration
がスローされます。 ジェネレーター式
を使用して返すだけでなく、直接使用することもできます。表現、そうですね。 。 。抽象的かもしれませんが、以下のコードを見れば理解できると思います。 <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:py;">def printNums():
for i in [1,2,3,4,5]:
yield i
def main():
for i in printNums():
print(i)
gener = (i for i in [1,2,3,4,5])
for i in gener:
print(i)
if __name__ == &#39;__main__&#39;:
main()</pre><div class="contentsignin">ログイン後にコピー</div></div>このうち、コード <code>(i for i in [1,2,3,4,5])
は printNums
関数と同等であり、そのコンテナーのタイプが生成されるので、type
を使用してそれを印刷して確認できます。 コードを変更すると、出力は次のようになります:
以上がPython のジェネレーターはどのように機能するのでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。