2009-12-25 55 views
15

我在django.template以下代碼:這個類如何實現「__iter__」方法而不實現「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) 

我感到困惑的部分是下面。這個__iter__方法是如何工作的?我找不到任何相應的next方法。

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

這是我知道如何實現__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 

在您的回答,請儘量使用示例代碼,而不是文字,因爲我的英語不是很好。謝謝。

回答

32

docs

如果容器對象的__iter__() 方法作爲發電機來實現, 它會自動返回一個 迭代器對象(在技術上,一個 發生器對象)供給 __iter__()next()方法。

11

__iter__方法返回一個python 發生器(見documentation),因爲它使用yield關鍵字。 生成器將自動提供next()方法;引用的文檔:

什麼使發電機如此緊湊是__iter __()和next()方法自動創建 。

編輯:

生成器是非常有用的。如果你對它們不熟悉,我建議你對它們進行讀取,然後玩弄一些測試代碼。

以下是關於StackOverflow迭代器和發生器的更多信息。

+0

是否意味着被客戶端代碼調用?我假設沒有,因爲它有__fname__形式 – danben 2009-12-25 02:45:48

+0

--fname--形式,其中那些破折號是下劃線 – danben 2009-12-25 02:46:25

+0

我不知道Django,但最終它只是Python語法。當需要爲Template對象創建一個迭代器時,它的'__iter __(self)'鉤子將被調用。然後它將返回一個具有正確next()方法的Generator對象。 – catchmeifyoutry 2009-12-25 02:52:14