J'étais curieux d'utiliser des variables statiques en python et je me suis retrouvé à: Pourquoi Python ne fonctionne-t-il pas avoir des variables statiques?

Dans la réponse acceptée, que j'ai trouvée informative, il est dit "Si vous voulez que le comportement de votre fonction change à chaque fois qu'elle est appelée, vous avez besoin d'un générateur".

Cependant, j'étais un peu confus, car l'exemple utilisé ici peut également être fait avec une classe:

class Foo(object):                                                              
    def __init__(self, bar):                                                    
        self.bar = bar                                                          

    def __call__(self):                                                         
        self.bar = self.bar * 3 % 5                                             
        return self.bar

foo = Foo(bar)                                                                  
print foo()                                                                     
print foo()

Cela a plus de sens pour moi (mais probablement uniquement parce que je n'ai pas utilisé correctement les générateurs auparavant).

Ma question est donc de savoir s'il existe un autre avantage à utiliser des générateurs par rapport aux classes lorsque la fonction doit changer de comportement à chaque appel.

1
oadams 16 oct. 2011 à 15:31

3 réponses

Une classe de générateur appropriée ressemble à ceci:

class Foo(object):                                                              
    def __init__(self, bar):                                                    
        self.bar = bar                                                          

    def __iter__(self):
        return self

    def next(self):
        self.bar = self.bar * 3 % 5                                             
        return self.bar

foo = Foo(3)                                                                  
print next(foo)                                                                     
print next(foo)

La fonction de générateur équivalent prend la moitié du code:

def Foo(bar):
    while True:
        bar = bar * 3 % 5   
        yield bar                                                          

foo = Foo(3)                                                                  
print next(foo)                                                                     
print next(foo)

Les fonctions de générateur ne sont qu'un raccourci pour le modèle d'itération de base le plus courant. Lorsque vous avez besoin de quelque chose de plus complexe, une classe le permet.

2
melwil 1 févr. 2018 à 16:07

Pour les générateurs, il n'y a pas d'autre moyen d'accéder à la variable, sauf en appelant une fonction, tandis que dans une variante basée sur une classe, vous pouvez la modifier directement. Cela peut être à la fois un avantage et un inconvénient selon votre cas d'utilisation. Le code est également plus simple. Pour une discussion plus détaillée, voir: http://wiki.python.org/moin/Generators

1
Vsevolod Dyomkin 16 oct. 2011 à 11:52

Il n'y a rien que vous puissiez faire avec un générateur que vous ne pourriez pas faire avec une classe.

La raison d'utiliser des générateurs est simplement qu'ils sont plus courts et, dans de nombreux cas, lisent plus naturellement que les classes. Évidemment, cela dépend de ce que vous faites. Dans l'exemple que vous donnez, vous voulez simplement effectuer à plusieurs reprises les mêmes opérations et cracher le nombre, donc un générateur est parfaitement logique. Pour les situations plus complexes, vous utiliseriez une classe.

2
Thomas K 16 oct. 2011 à 11:49