Maison > Article > développement back-end > Définition du générateur Python et analyse d'exemples d'utilisation simples
Cet article présente principalement la définition et l'utilisation simple des générateurs Python. Il analyse en détail les concepts, principes, méthodes d'utilisation et précautions de fonctionnement associées sous forme d'exemples. Les amis dans le besoin peuvent s'y référer
.Les exemples de cet article décrivent la définition et l'utilisation simple des générateurs Python. Partagez-le avec tout le monde pour votre référence, les détails sont les suivants :
1. Qu'est-ce qu'un générateur
En Python, à cause de la mémoire. limitations, la capacité de la liste est définitivement limitée. Par exemple, si nous créons une liste contenant 100 millions d'éléments, Python ouvrira d'abord suffisamment d'espace en mémoire pour stocker la liste contenant 100 millions d'éléments, puis permettra à l'utilisateur d'utiliser la liste. Cela peut entraîner les problèmes suivants : <.>
1. Il n'y a pas assez d'espace mémoire dans la mémoire pour stocker cette liste, ce qui fait que la liste ne peut pas être créée 2. Même si la liste est créée avec succès, il faudra quand même longtemps, ce qui entraîne une efficacité du programme Faible 3. Si l'utilisateur souhaite accéder uniquement aux premiers éléments de la liste, l'espace occupé par la plupart des éléments de la liste suivante sera gaspilléAfin de résoudre efficacement les problèmes ci-dessus, Python Un nouveau mécanisme de "
tout en bouclant et en calculant " est introduit signifie que lorsque l'utilisateur a besoin d'utiliser. un objet, Python ouvrira de l'espace mémoire et le créera selon les règles prédéfinies. Cet objet est destiné aux utilisateurs, au lieu de créer tous les objets à l'avance et de les fournir ensuite aux utilisateurs pour qu'ils les utilisent comme une liste. Ce mécanisme est appelé générateur en Python.
2. Création du générateur
A. La formule push du générateur
et List push est similaire, sauf que la compréhension du générateur utilise () au lieu de [], et le générateur est finalement renvoyé à la place de la listeg=((i+2)**2 for i in range(2,30)) #g是一个生成器 print(g) #g为空,里面包含任何元素Le résultat de l'exécution est :
2e801a85d554189dae3d2de3ce9809fc à 0x0000000002263150>
B. le mot-clé de rendement
contient le mot-clé de rendement dans une définition de fonction, alors cette fonction n'est plus une fonction ordinaire, mais un générateur[Explication] : L'instruction rendement peut mettre en pause une fonction et renvoyer ses résultats intermédiaires. La fonction utilisant cette instruction sauvegardera l'environnement d'exécution et restaurera si nécessaire <.>
Résultat d'exécution :def fib(max): n,a,b=0,0,1 while n<max: #print(b) yield b a,b=b,a+b n+=1 return 'done' f=fib(6) print(f)420e1f45ef0b5676cb7908ed350fc3ee
[Remarque] : La différence entre fonctions ordinaires et fonctions qui deviennent des générateurs :
Les fonctions ordinaires sont exécutées séquentiellement et renvoient ou la dernière ligne est rencontrée. L'instruction de fonction renvoie. La fonction qui devient un générateur est exécutée à chaque fois que la méthode __next__() est appelée et retourne lorsqu'elle rencontre une instruction rendement. Lorsqu'elle est à nouveau exécutée, l'exécution continue à partir de l'instruction rendement renvoyée la dernière fois<.> Résultat d'exécution :
f=fib(6) print(f) print(f.__next__()) print(f.__next__()) print('暂停一下') print(f.__next__()) print(f.__next__())
2fb4b1abaf61a8a86847260d52affa99
11Pause un instant
3. Méthode du générateur (Référence : Bole Online)
2
3
Méthode 1.close() : fermez manuellement la fonction du générateur, les appels suivants renverront directement l'exception StopIteration
Résultat d'exécution :
def func(): yield 1 yield 2 yield 3 g=func() g.__next__() g.close() #手动关闭生成器 g.__next__() #关闭后,yield 2和yield 3语句将不再起作用
Traceback (dernier appel le plus récent) :
Fichier "E:py3DemoHellogeneratorDemo.py", ligne 9, dans d61694b5bf3bcd79692d5c462d21d85b[流程解释]:
a.通过g.send(None)或g.__next__()启动生成器函数,并执行到第一个yield语句结束的位置并将函数挂起。此时执行完了yield语句,但是没有给receive赋值,因此yield value会输出value的初始值0
b.g.send('aaa')先将字符串‘aaa'传入到生成器函数中并赋值给receive,然后从yield语句的下一句重新开始执行函数(第五句),计算出value的值后返回到while头部开始新一轮的循环,执行到yield value语句时停止,此时yield value会输出‘Got:aaa',然后挂起
c.g.send(3)重复步骤b,最后输出结果为‘Got:3'
d.g.send('end')会使程序执行break然后跳出循环,从而函数执行完毕,得到StopIteration异常
4.throw()方法:向生成器发送一个异常。
def gen(): while True: try: yield 'normal value' #返回中间结果,此处的yield和return的功能相似 yield 'normal value2' print('I am here') except ValueError: print('We got ValueError') except Exception: print('Other errors') break g=gen() print(g.__next__()) print(g.throw(ValueError)) print(g.__next__()) print(g.throw(TypeError))
运行结果:
Traceback (most recent call last):
File "E:\py3Demo\Hello\generatorDemo.py", line 17, in 4225fa317875f3e92281a7b1a5733569
print(g.throw(TypeError))
StopIteration
normal value
We got ValueError
normal value
normal value2
Other errors
[解释]:
a.print(g.__next__())会输出normal value,并停在yield 'normal value2'之前
b.由于执行了g.throw(ValueError),所以回跳过后续的try语句,即yield ‘normal value2'不会执行,然后进入到except语句,打印出‘We got ValueError'。之后再次进入到while语句部分,消耗一个yield,输出normal value
c.print(g.__next__())会执行yield ‘normal value2'语句,并停留在执行完该语句后的位置
d.g.throw(TypeError)会跳出try语句,因此print('I am here')不会被执行,然后打印‘Other errors',并执行break语句跳出while循环,然后到达程序结尾,打印StopIteration异常的信息
四、生成器的运用
import time def consumer(name): print('%s准备吃包子啦!' %name) while True: baozi=yield #接收send传的值,并将值赋值给变量baozi print('包子[%s]来了,被[%s]吃了!' %(baozi,name)) def producer(name): c1=consumer('A') #把函数变成一个生成器 c2=consumer('B') c1.__next__()#调用这个方法会走到yield处暂时返回 c2.__next__() print('开始准备做包子啦!') for i in range(10): time.sleep(1) print('做了一个包子,分成两半') c1.send(i) c2.send(i) producer('Tomwenxing')
运行结果:
A准备吃包子啦!
B准备吃包子啦!
开始准备做包子啦!
做了一个包子,分成两半
包子[0]来了,被[A]吃了!
包子[0]来了,被[B]吃了!
做了一个包子,分成两半
包子[1]来了,被[A]吃了!
包子[1]来了,被[B]吃了!
做了一个包子,分成两半
包子[2]来了,被[A]吃了!
包子[2]来了,被[B]吃了!
做了一个包子,分成两半
包子[3]来了,被[A]吃了!
包子[3]来了,被[B]吃了!
做了一个包子,分成两半
包子[4]来了,被[A]吃了!
包子[4]来了,被[B]吃了!
做了一个包子,分成两半
包子[5]来了,被[A]吃了!
包子[5]来了,被[B]吃了!
做了一个包子,分成两半
包子[6]来了,被[A]吃了!
包子[6]来了,被[B]吃了!
做了一个包子,分成两半
包子[7]来了,被[A]吃了!
包子[7]来了,被[B]吃了!
做了一个包子,分成两半
包子[8]来了,被[A]吃了!
包子[8]来了,被[B]吃了!
做了一个包子,分成两半
包子[9]来了,被[A]吃了!
包子[9]来了,被[B]吃了!
相关推荐:
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!