2009-12-24 3 views
0

je ne sais pas "self._iterator = iter (self._container)" dans le code suivant.je ne sais pas pourquoi iter (pas __iter__) fonction utiliser à cet endroit, quelle est la moyenne de iter dans ce code

dans django.http:

class HttpResponse(object): 
    def __iter__(self): 
     self._iterator = iter(self._container) 
     return self 

    def next(self): 
     chunk = self._iterator.next() 
     if isinstance(chunk, unicode): 
      chunk = chunk.encode(self._charset) 
     return str(chunk) 

je lis les api:

Retour un objet iterator. Le premier argument est interprété très différemment en fonction de la présence du second argument. Sans un second argument, o doit être un objet de collection qui prend en charge le protocole d'itération (la __iter__() de la méthode), ou il doit prendre en charge le protocole de séquence (méthode __getitem__() avec des arguments entiers commençant à 0). Si elle ne prend pas en charge de ces protocoles, TypeError est élevé. Si le second argument, sentinel, est donné, alors o doit être un objet appelable . L'itérateur créé dans ce cas appellera o sans arguments pour chaque appel à sa méthode next() ; si la valeur retournée est égale à sentinelle, StopIteration sera élevé, sinon la valeur sera retourné. Une application utile de la deuxième forme de iter() est de lire lignes d'un fichier jusqu'à une certaine ligne est atteinte. L'exemple suivant lit un fichier jusqu'à ce que « STOP » est atteint:

mais je ne savent pas ce que la fonction iter fait.

i know the __iter__: 
class a(object): 
    def __init__(self,x=10): 
     self.x = x 
    def __iter__(self): 
     return self 
    def next(self): 
     if self.x > 0: 
       self.x-=1 
       return self.x 
     else: 
       raise StopIteration 

S'il vous plaît essayer d'utiliser le code, plutôt que du texte, parce que mon anglais est pas très bon, merci

Répondre

1

Itérateur peut itérer:

for item in mylist: 
    print item 

for key,item in enumerate(mylist): 
    print key,":",item 

for i in range(0,50): 
    print i 

Pour utiliser for item in X, X doit être itérables.

Vous pouvez rendre votre classe itérable en ajoutant next(self) etc, comme dans votre exemple. Donc, avec

class a(object): 
    def __init__(self,x=10): 
     self.x = x 
    def __iter__(self): 
     return self 
    def next(self): 
     if self.x > 0: 
      self.x-=1 
      return self.x 
     else: 
      raise StopIteration 

Ensuite, vous pouvez faire

ainst = a() 
for item in aisnt: 
    print item 
0

HttpResponse est une classe qui permet de stocker les données de chaîne. Les données sont stockées dans une variable membre appelée _container. Supposons que hr est une instance de HttpResponse avec des données à l'intérieur. Lorsque vous appelez iter(hr), vous devez récupérer un itérateur. Cet itérateur renvoie les données de la variable membre _container.

Cette classe "enveloppe" le membre _container afin qu'il puisse toujours renvoyer du texte non-Unicode. Parce que cette classe a une fonction de la méthode __iter__(), lorsque vous appelez iter() vous appelez vraiment la fonction de la méthode __iter__() spéciale. Cette fonction de méthode appelle effectivement iter() sur la variable membre _container pour obtenir un itérateur pour son contenu. Mais ensuite, il enregistre cet itérateur dans la variable membre _iterator et renvoie self. Maintenant, il est prêt à itérer.

Il y a une fonction de la méthode next() définie. Si le type de la variable _container est Unicode, il appelle encode() pour coder l'Unicode dans un codage et retourner un non-Unicode. Il utilise une autre variable membre, _charset, pour savoir quel jeu de caractères utiliser pour le codage.Si le type de la variable container n'est pas Unicode, il doit s'agir d'un type de chaîne ordinaire et les données sont simplement renvoyées telles quelles. De cette manière, l'objet "enveloppé" dans cette classe peut être itéré et retourner toujours du texte non-Unicode. Je suis surpris par cette implémentation du protocole itérateur. Quand il vous renvoie un itérateur, il renvoie simplement self, donc si vous appelez deux fois iter(), vous ne récupérez pas deux itérateurs utilisables. Cela semble être dangereux. Je suppose que le code Django ne fait jamais rien de pareil.