Remarque : La méthode next() du générateur est next() en python 2, mais en python 3 c'est __next__()
[next est précédé et suivi de deux traits de soulignement]
Mettre une fonction Devenant un générateur, une fonction avec rendement n'est plus une fonction ordinaire. Autrement dit : une fonction avec rendement est un générateur. Elle est différente d'une fonction ordinaire. La génération d'un générateur ressemble à un appel de fonction, mais n'exécutera aucun code de fonction tant que next() ne sera pas appelé dessus (il sera automatiquement appelé). une boucle for next()) démarre l'exécution. Bien que le flux d'exécution soit toujours exécuté en fonction du flux de la fonction, chaque fois qu'une instruction de rendement est exécutée, elle sera interrompue et une valeur d'itération sera renvoyée. La prochaine exécution continuera à partir de l'instruction de rendement suivante. Il semble qu'une fonction soit interrompue plusieurs fois par Yield lors d'une exécution normale, et chaque interruption renvoie la valeur d'itération actuelle via Yield.
Les avantages de rendement sont évidents. La réécriture d'une fonction en tant que générateur lui donne la possibilité d'itérer par rapport à l'utilisation d'une instance d'une classe pour enregistrer l'état afin de calculer la valeur du prochain next(), pas. seul le code est concis, mais le flux d'exécution est également extraordinairement clair.
#!/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]
Conclusion :
De la comparaison des deux méthodes ci-dessus, on peut voir que l'ajout d'un objet itérable après le rendement de peut convertir chaque élément de l'objet itérable. Les éléments en produisent un par Un. Par rapport à Yield, le code est plus concis et la structure est plus claire.
Recommandations d'apprentissage associées : Tutoriel vidéo Python
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!