ジェネレーターの next() メソッドは、Python 2 では next() ですが、Python 3 では __next__() [next の前後には 2 つのアンダースコアが続きます]
関数をジェネレーターに変える yield を備えた関数は、もはや普通の関数ではありません。つまり: yield を持つ関数はジェネレーターです。通常の関数とは異なります。ジェネレーターの生成は関数呼び出しのように見えますが、 next() が呼び出されるまで関数コードは実行されません (関数は自動的に呼び出されます)。 for ループ next()) が実行を開始します。実行フローは関数の流れに従って実行されますが、yield 文が実行されるたびに中断されて反復値が返され、次の実行は次の yield 文から継続されます。通常の実行中に関数が yield によって数回中断され、各中断が yield を通じて現在の反復値を返しているように見えます。
yield の利点は明白です。関数をジェネレーターとして書き直すことで、反復処理が可能になります。クラスのインスタンスを使用して状態を保存し、次の next() の値を計算するのと比較すると、 、コードが簡潔であるだけでなく、実行プロセスもより単純であり、非常に明確です。
#!/usr/bin/env python # -*- coding: utf-8 -*-def fab(max): n , a, b = 0, 0 , 1 while n < max: print(b) a, b = b, a + b n = n + 1if __name__ == '__main__': fab(6) # 1 1 2 3 5 8
#!/usr/bin/env python # -*- coding: utf-8 -*-def fab(max): n , a, b = 0, 0 , 1 while n < max: yield b a, b = b, a + b n = n + 1if __name__ == '__main__': for n in fab(6): # 1 1 2 3 5 8 print(n)
#!/usr/bin/env python # -*- coding: utf-8 -*-from inspect import isgeneratorfunction def fab(max): n , a, b = 0, 0 , 1 while n < max: yield b a, b = b, a + b n = n + 1if __name__ == '__main__': f1 = fab(3) # True fab是一个generator function print(isgeneratorfunction(fab)) # False fab(3)不是一个generator function # 而fab(3)是调用fab返回的一个generator print(isgeneratorfunction(fab(3)))
#!/usr/bin/env python # -*- coding: utf-8 -*-def read_file(fpath): BLOCK_SIZE = 100 with open(fpath, "rb") as f: while True: block = f.read(BLOCK_SIZE) if block: yield block else: returnif __name__ == '__main__': fpath = "/home/exercise-python3.7.1/vote/mysite/mysite/polls/test.txt" read_gen = read_file(fpath) print(read_gen.__next__()) print(read_gen.__next__()) print(read_gen.__next__()) print(read_gen.__next__()) # for循环会自动调用generatr的__next__()方法,故输出效果同如上的4个print 【内容较短,4个print就将test.txt中的内容输出完了】 for data in read_gen: print(data)
#!/usr/bin/env python # -*- coding: utf-8 -*-if __name__ == '__main__': astr = "ABC" alist = [1, 2, 3] adict = {"name": "wangbm", "age": 18} # generate agen = (i for i in range(4, 8)) def gen(*args, **kw): for item in args: for i in item: yield i new_list = gen(astr, alist, adict, agen) print(list(new_list)) # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
#!/usr/bin/env python # -*- coding: utf-8 -*-if __name__ == '__main__': astr = "ABC" alist = [1, 2, 3] adict = {"name": "wangbm", "age": 18} # generate agen = (i for i in range(4, 8)) def gen(*args, **kw): for item in args: yield from item new_list = gen(astr, alist, adict, agen) print(list(new_list)) # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]結論:
上記 2 つの方法を比較すると、 yield from の後に反復可能オブジェクトを追加すると、反復可能オブジェクト内の各項目を 1 つずつ変換できることがわかります。 yield と比較すると、コードはより簡潔になり、構造がより明確になります。
関連する学習に関する推奨事項:
以上がPythonの収量と使用方法からの収量の概要と詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。