2009-12-25 11 views
15

Tengo el siguiente código en django.template:¿Cómo implementa esta clase el método "__iter__" sin implementar "next"?

class Template(object): 
    def __init__(self, template_string, origin=None, name='<Unknown Template>'): 
     try: 
      template_string = smart_unicode(template_string) 
     except UnicodeDecodeError: 
      raise TemplateEncodingError("Templates can only be constructed from unicode or UTF-8 strings.") 
     if settings.TEMPLATE_DEBUG and origin is None: 
      origin = StringOrigin(template_string) 
     self.nodelist = compile_string(template_string, origin) 
     self.name = name 

    def __iter__(self): 
     for node in self.nodelist: 
      for subnode in node: 
       yield subnode 

    def render(self, context): 
     "Display stage -- can be called many times" 
     return self.nodelist.render(context) 

La parte que me gustaría saber es abajo. ¿Cómo funciona este método __iter__? No puedo encontrar ningún método correspondiente next.

def __iter__(self): 
     for node in self.nodelist: 
      for subnode in node: 
       yield subnode 

Ésta es la única manera que sé cómo implementar __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 
ainst = a() 
for item in aisnt: 
    print item 

En sus respuestas, por favor intente usar ejemplos de código en lugar de texto, porque mi Inglés no es muy buena. Gracias.

Respuesta

32

Desde el docs:

Si el método de un objeto contenedor __iter__() se implementa como un generador, volverá automáticamente un objeto iterador (técnicamente, un objeto generador) el suministro de la __iter__() y next() métodos.

11

Eso __iter__ método devuelve una pitón generador de (ver el documentation), ya que utiliza la palabra clave yield. El generador proporcionará el método next() automáticamente; citando la documentación:

Lo que hace que los generadores tan compacto es que el __iter __() y next() se crean métodos automáticamente.

EDIT:

generadores son realmente útiles. Si no estás familiarizado con ellos, te sugiero que leas sobre ellos y juegues con algunos códigos de prueba.

Aquí hay más información sobre iteradores y generadores de StackOverflow.

+0

¿Está destinado a ser llamado por código de cliente? Asumí que no, ya que tiene el formulario __fname__ – danben

+0

el formulario --fname-- donde esos guiones están subrayados – danben

+0

No tengo ni idea de Django, pero al final es solo la sintaxis de Python. Cuando se necesita crear un iterador para un objeto Template, se llamará a su gancho '__iter __ (self)'. Luego devolverá un objeto generador que tiene el método siguiente correcto(). – catchmeifyoutry

Cuestiones relacionadas