Python中实现iterator

xiao911 8年前
   <p><img src="https://simg.open-open.com/show/95862aa0f3216717dd43fb62b7cdebf3.jpg"></p>    <p>今天创建了一个实体类,大致如下:</p>    <pre>  <code class="language-python">class Account():      def __init__(self,                   account_name,                   account_type,                   account_cost,                   return_amount=0):          self.account_name  = account_name   # 账户名          self.account_type  = account_type   # 账户类型          self.account_cost  = account_cost   # 月结费用          self.return_amount = return_amount  # 返还金额</code></pre>    <p>然后创建一个实体列表:</p>    <pre>  <code class="language-python">accounts = [Account("张三", "年费用户", 450.00, 50),              Account("李四", "月结用户", 100.00),              Account("杨不悔", "月结用户", 190.00, 25),              Account("任我行", "月结用户", 70.00, 10),              Account("凌未风", "年费用户", 400.00, 40)]</code></pre>    <p>我想要执行next()功能,也就是需要的时候“next”一下,得到List中的下一个元素。直接测试一下:</p>    <p><img src="https://simg.open-open.com/show/eb8f7539be0289ee82ce476375f96049.png"></p>    <p>结果发现List不支持next()特性。这时候,List只是一个 <em>iterable</em> ,而不是 <em>iterator</em> 。 <em>iterable</em> 和 <em>iterator</em> 的区别如下:</p>    <ul>     <li><em>iterable</em> —— 只实现了__iter__的对象;</li>     <li><em>iterator</em> —— 同时实现了__iter__和__next__方法的对象。</li>    </ul>    <p>其中,__iter__返回 <em>iterator</em> 对象,__next__则返回迭代过程的下一个元素。</p>    <h3>1. 让列表成为 <em>iterator</em></h3>    <p>要让前面的accounts List成为 <em>iterator</em> 只需简单的一个iter()函数:</p>    <pre>  <code class="language-python">accounts_iterator = iter(accounts)  (next(accounts_iterator)).account_name</code></pre>    <p>结果如下图所示:</p>    <p><img src="https://simg.open-open.com/show/0db2c0ccef558f0458ebe9630046ac64.png"></p>    <p>这么简单的函数,估计还是有不少Python开发者不知道吧?</p>    <h3>2. 自定义 <em>iterator</em> 对象</h3>    <p>扩展开来讲,如何定义自己的 <em>iterator</em> 对象呢?其实也就是按照上面的定义,实现__iter__和__next__方法。</p>    <p>我们接下来定义一个AccountIterator类:</p>    <pre>  <code class="language-python">class AccountIterator():      def __init__(self, accounts):          self.accounts  = accounts  # 账户集合          self.index     = 0        def __iter__(self):          return self        def __next__(self):          if self.index >= len(self.accounts):              raise StopIteration("到头了...")          else:              self.index += 1              return self.accounts[self.index-1]</code></pre>    <p>运行结果如:</p>    <p><img src="https://simg.open-open.com/show/0db2c0ccef558f0458ebe9630046ac64.png"></p>    <p>通过这一阵折腾,next()功能就实现了。Python有不少意外的功能,还等着我们不断去探究,也许这就是Python的魅力及极客之处。</p>    <p>来自:https://zhuanlan.zhihu.com/p/23292802</p>    <p> </p>