Maison >développement back-end >Tutoriel Python >Introduction détaillée au rendement

Introduction détaillée au rendement

巴扎黑
巴扎黑original
2017-09-04 11:36:381755parcourir

Le mot anglais rendement signifie production. J'étais très confus lorsque je suis entré en contact avec Python pour la première fois et je n'ai jamais compris comment utiliser rendement.

Je sais à peu près que le rendement peut être utilisé pour insérer des données dans la valeur de retour d'une fonction, comme dans l'exemple suivant :

def addlist(alist):
    for i in alist:
        yield i + 1

Supprimer chaque élément d'une liste, puis des trucs que je + 1 go. Retirez ensuite chaque élément en appelant :

alist = [1, 2, 3, 4]
for x in addlist(alist):
    print x,

Il s'agit bien d'un exemple d'application de rendement

1 Fonction contenant du rendement

Si vous voyez une fonction Contient du rendement, ce qui signifie que cette fonction est déjà un générateur et que son exécution sera très différente des autres fonctions ordinaires. Par exemple, la fonction simple suivante :

def h():
    print 'To be brave'
    yield 5
h()

Vous pouvez voir qu'après avoir appelé h(), l'instruction print n'est pas exécutée ! C'est le rendement, alors comment exécuter l'instruction print ? C'est la question qui sera abordée plus tard. Grâce à la discussion et à l'étude qui suivront, vous comprendrez comment fonctionne le rendement.

2. rendement est une expression

Avant Python 2.5, rendement était une déclaration, mais maintenant en 2.5, rendement est une expression (Expression), telle que :

m = rendement 5

La valeur de retour de l'expression (rendement 5) sera attribuée à m, il est donc faux de penser que m = 5. Alors, comment obtenir la valeur de retour de (rendement 5) ? Vous devez utiliser la méthode send(msg) qui sera présentée plus tard.

3. Voir le principe à travers l'instruction next()

Maintenant, révélons le principe de fonctionnement du rendement. Nous savons que notre h() ci-dessus n'a pas été exécuté après avoir été appelé, car il a une expression de rendement, nous le laissons donc s'exécuter via l'instruction next(). L'instruction next() reprendra l'exécution du générateur jusqu'à la prochaine expression de rendement. Par exemple :

def h():
    print 'Wen Chuan'
    yield 5
    print 'Fighting!'
c = h()
c.next()

Après l'appel de c.next(), h() commence à s'exécuter jusqu'à ce qu'il rencontre le rendement 5, le résultat de sortie est donc :

Wen Chuan

Quand Lorsque nous appellerons à nouveau c.next(), l'exécution se poursuivra jusqu'à ce que la prochaine expression de rendement soit trouvée. Puisqu'il n'y a pas de rendement plus tard, une exception sera levée :

Wen Chuan
Fighting!
Traceback (most recent call last):
  File "/home/evergreen/Codes/yidld.py", line 11, in <module>
    c.next()
StopIteration

4. send(msg) et next()

Après avoir compris comment next() provoque la fonction contenant le rendement. exécutez, regardons une autre fonction très importante send(msg). En fait, next() et send() ont des fonctions similaires dans un certain sens. La différence est que send() peut transmettre la valeur de l'expression de rendement, tandis que next() ne peut pas transmettre une valeur spécifique et ne peut transmettre aucune. Par conséquent, nous pouvons voir que

c.next() et c.send(None) ont le même effet.

Regardez cet exemple :

def h():
    print &#39;Wen Chuan&#39;,
    m = yield 5  # Fighting!
    print m
    d = yield 12
    print &#39;We are together!&#39;
c = h()
c.next()  #相当于c.send(None)
c.send(&#39;Fighting!&#39;)  #(yield 5)表达式被赋予了&#39;Fighting!&#39;

Le résultat de sortie est :

Wen Chuan Fighting !

Il convient de rappeler que le premier appel s'il vous plaît utilisez l'instruction next() ou send(None). Vous ne pouvez pas utiliser send pour envoyer une valeur non None, sinon une erreur se produira car il n'y a pas d'instruction rendement pour recevoir cette valeur.

5. Les valeurs de retour de send(msg) et next()

send(msg) et next() ont des valeurs de retour très spéciales. le suivant Un paramètre d’une expression de rendement. Par exemple, si le rendement est de 5, 5 sera renvoyé. Avez-vous compris quelque chose ici ? Dans le premier exemple de cet article, en parcourant le générateur pour i dans alist, alist.Next() est en fait appelé à chaque fois, et la valeur de retour de alist.Next() à chaque fois est le paramètre de rendement, c'est-à-dire nous commençons à penser que quelque chose est enfoncé. Continuons l'exemple ci-dessus :

def h():
    print &#39;Wen Chuan&#39;,
    m = yield 5  # Fighting!
    print m
    d = yield 12
    print &#39;We are together!&#39;
c = h()
m = c.next()  #m 获取了yield 5 的参数值 5
d = c.send(&#39;Fighting!&#39;)  #d 获取了yield 12 的参数值12
print &#39;We will never forget the date&#39;, m, &#39;.&#39;, d

Résultat de sortie :

Wen Chuan Fighting!
We will never forget the date 5 . 12

6. throw() et close() interrompent le générateur

Le générateur d'interruption est un outil très flexible. technique pour terminer le générateur en lançant une exception GeneratorExit. La méthode Close() a la même fonction, en fait, elle appelle throw(GeneratorExit) en interne. Voyons :

def close(self):
    try:
        self.throw(GeneratorExit)
    except (GeneratorExit, StopIteration):
        pass
    else:
        raise RuntimeError("generator ignored GeneratorExit")
# Other exceptions are not caught

Par conséquent, lorsque nous appelons la méthode close(), puis que nous appelons next() ou send(msg), une exception sera levée :

Traceback (most recent call last):
  File "/home/evergreen/Codes/yidld.py", line 14, in <module>
    d = c.send(&#39;Fighting!&#39;)  #d 获取了yield 12 的参数值12
StopIteration

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn