zoukankan      html  css  js  c++  java
  • Iterator Protocol

      1 Iterator Protocol - Python 描述符协议
      2 
      3 先看几个有关概念,
      4     iterator 迭代器,
      5         一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多的元素可返回的时候 raises StopIteration 的对象,
      6         被称为 iterator(迭代器).
      7         在 python 中, 迭代器 'iterator' 同时也实现了 __iter__ 方法, 故 iterators are iterable.
      8         经典迭代器 'classic iterators' 从一个集合'collection'中返回元素.
      9         生成器 'generator' 也是迭代器, 但可能灵活些, 请参考 generator 一文。
     10             例,
     11                 >>> A = iter('Ads')
     12                 >>> A
     13                 <iterator object at 0x00000000036D7320>
     14                 >>> type(A)
     15                 <type 'iterator'>
     16                 >>> dir(A)
     17                 ['__class__', ... ..., '__iter__', ... ..., 'next']
     18                 >>> A.next()
     19                 'A'
     20                 >>> A.next()
     21                 'd'
     22                 >>> A.next()
     23                 's'
     24                 >>> A.next()
     25                 Traceback (most recent call last):
     26                   File "<input>", line 1, in <module>
     27                 StopIteration
     28 
     29         iterator
     30             Any object that implements the __next__
     31             no-argument method which returns the
     32             next item in a series, or raises StopItera
     33             tion when there are no more items. Python
     34             iterators also implement the __iter__
     35             method so they are also iterable. Classic
     36             iterators, according to the original design
     37             pattern, return items from a collection. A
     38             generator is also an iterator, but it’s more
     39             flexible. See generator
     40 
     41     iterable 可迭代,
     42         一个对象,如果该对象可以通过内置方法 'iter' 获得可以个 'iterator',则称该对象是可迭代对象 'iterable'
     43             如,
     44                 >>> A = iter('ABCCcvsds')
     45                 >>> A
     46                 <iterator object at 0x00000000036D7320>
     47                 >>> type(A)
     48                 <type 'iterator'>
     49 
     50         一个可迭代对象 'iterable object' 可以用于 循环'loops', 列表推导'comprehensions', 元祖拆包'tuple unpacking'.
     51         实现了 __iter__ 方法, 返回迭代器'iterator'的对象是可迭代的对象'iterable'. 序列'sequences' 是可迭代对象.
     52         实现了 __getitem__ 方法的对象也有可能是可迭代对象.
     53 
     54         iterable
     55             Any object from which the iter built-in
     56             function can obtain an iterator. An iterable
     57             object works as the source of items in for
     58             loops, comprehensions and tuple unpack‐
     59             ing. Objects implementing an __iter__
     60             method returning an iterator are iterable.
     61             Sequences are always iterable; other objects
     62             implementing a __getitem__ method may
     63             also be iterable.
     64 
     65     iterable unpacking 可迭代对象拆包
     66         与元祖拆白 'tuple unpacking' 同义. 应用于 'parallel assignment'.
     67             例,
     68                 >>> a = (1,2)
     69                 >>> b,c = a
     70                 >>> a
     71                 (1, 2)
     72                 >>> b
     73                 1
     74                 >>> c
     75                 2
     76                 >>> c,b = b,c
     77                 >>> a
     78                 (1, 2)
     79                 >>> b
     80                 2
     81                 >>> c
     82                 1
     83 
     84         parallel assignment
     85             Assigning to several variables from items in
     86             an iterable, using syntax like a, b = [c,
     87             d] — also known as destructuring assign‐
     88             ment. This is a common application of tuple
     89             unpacking.
     90 
     91 进一步了解一下儿迭代器对象 'Iterator Objects''Iterator Protocol',
     92     Iterator Objects
     93         python 中有两种 迭代器对象 'iterator objects'.
     94 
     95         一种是 序列迭代器 'sequence iterator', 用于对'序列对象' __getitem__ 方法的支持.
     96 
     97         另一种是,上例子中常见的迭代器: 一个可调用对象'callable object', 在其上调用 next()
     98         方法, 依次放回序列中的元素, 迭代结束的时候返回 StopIteration error(sentinel value).
     99 
    100         迭代器相关源码,
    101             '第一种'迭代器相关,
    102                 PyTypeObject PySeqIter_Type
    103                     python 类型对象-'PySeqIter_Type' 为迭代器对象的'类型对象', 由 PySeqIter_New() 函数产生.
    104                     也是通过 iter(iterable) 内建函数所得到'序列'的类型对象.
    105 
    106                 int PySeqIter_Check(op)
    107                     当 op 是 PySeqIter_Type 类型的时候, 函数返回 true
    108 
    109                 PyObject* PySeqIter_New(PyObject *seq)
    110                     创建一个迭代器对象, 迭代结束后 raises IndexError
    111 
    112             '另一种'迭代器相关,
    113               PyTypeObject PyCallIter_Type
    114                   由 PyCallIter_New() 创建的可'指定' sentinel value 的迭代器的类型对象.  iter(callable, sentinel value)
    115 
    116               int PyCallIter_Check(op)
    117                   当 op 是 PyCallIter_Type 类型的时候, 函数返回 true
    118 
    119               PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)
    120                   创建一个迭代器对象, 迭代返回 sentinel value 结束, 并 raises IndexError
    121                   第一个参数是任何 python callable 的对象.
    122 
    123              例子,
    124                 第一种'迭代器
    125                     >>> abc = [1,2,3,"S",4,5]
    126                     >>> a = iter(abc)
    127                     >>> a
    128                     <listiterator object at 0x00000000037E0668>
    129                     >>> a.next()
    130                     1
    131                     >> a.next()
    132                     2
    133                     >>> a.next()
    134                     3
    135                     >>> a.next()
    136                     'S'
    137                     >>> a.next()
    138                     4
    139                     >>> a.next()         # 当迭代器中没有新的数据的时候 StopIteration
    140                     Traceback (most recent call last):
    141                       File "<input>", line 1, in <module>
    142                     StopIteration
    143                     >>> a                # StopIteration 后迭代器对象还存在
    144                     <listiterator object at 0x00000000037E0668>
    145                     >>> a.next()         # 迭代器返回最后一个数据后,如果想再获取其中的元素, 需要再次生成新的迭代器对象
    146                     Traceback (most recent call last):
    147                       File "<input>", line 1, in <module>
    148                     StopIteration
    149 
    150                 另外一种'迭代器
    151                     >>> b = iter(abc.pop, "S")       # abc.pop 是一个 callable 的对象,  指定 StopIteration 的值'S'
    152                     >>> b
    153                     <callable-iterator object at 0x00000000037E0668>
    154                     >>> b.next()
    155                     4
    156                     >>> b.next()                     # next 方法得到元素 'S', raises StopIteration
    157                     Traceback (most recent call last):
    158                       File "<input>", line 1, in <module>
    159                     StopIteration
    160 
    161     Iterator Protocol
    162         python 在 C 层面有2个函数跟 迭代器 'iterator' 相关,
    163 
    164             int PyIter_Check(PyObject *o)
    165                 如果 对象 o 支持 迭代器协议 interator protocol 返回 true.
    166 
    167             PyObject* PyIter_Next(PyObject *o)
    168                 返回迭代 'iteration' 的下一个元素.
    169                 o 必须是一个迭代器(*** 注意,该函数本身并不对这一点做验证; 有使用者保证传入的是 iterator),
    170                 如果没有可以返回的元素, 返回 return NULL (没有exception 描述);
    171                 如果在获取元素的时候发生了任何的错误 errors, 返回 return NULL 即相应的 exception 描述.
    172 
    173             python 官方示例,
    174                 PyObject *iterator = PyObject_GetIter(obj);
    175                 PyObject *item;
    176 
    177                 if (iterator == NULL) {
    178                     /* propagate error */
    179                 }
    180 
    181                 while (item = PyIter_Next(iterator)) {
    182                     /* do something with item */
    183                     ...
    184                     /* release reference when done */
    185                     Py_DECREF(item);
    186                 }
    187 
    188                 Py_DECREF(iterator);
    189 
    190                 if (PyErr_Occurred()) {
    191                     /* propagate error */
    192                 }
    193                 else {
    194                     /* continue doing useful work */
    195                 }
      iterator 应用的经典示例,
          with open('mydata.txt') as fp:
              for line in iter(fp.readline, ''):
                  process_line(line)
  • 相关阅读:
    Qt多文档实现屏幕空间(类似监控多画面)效果
    python 使用ctypes调用C/C++ dll
    C++回调函数理解使用
    Qt MDI子窗口图标设置问题
    CentOS 7安装Qt5.12.1过程
    linux遇到xxx is not in the sudoers file.This incident will be reported的问题
    3D建模的类型:哪种最适合您的需求?
    letter-shell | 一个功能强大的嵌入式shell(转)
    EasyLogger | 一款轻量级且高性能的日志库(转)
    Linux下开发stm32(一) | 使用gcc-arm-none-eabi工具链编译(转)
  • 原文地址:https://www.cnblogs.com/zzyzz/p/7615699.html
Copyright © 2011-2022 走看看