Iterator Protocol - Python 描述符协议
Iterator Protocol - Python 描述符协议
先看几个有关概念,
iterator 迭代器,
一个实现了无参数的 __next__ 方法, 并返回 '序列'中下一个元素,在没有更多的元素可返回的时候 raises StopIteration 的对象,
被称为 iterator(迭代器).
在 python 中, 迭代器 'iterator' 同时也实现了 __iter__ 方法, 故 iterators are iterable.
经典迭代器 'classic iterators' 从一个集合'collection'中返回元素.
生成器 'generator' 也是迭代器, 但可能灵活些, 请参考 generator 一文。
例,
>>> A = iter('Ads')
>>> A
<iterator object at 0x00000000036D7320>
>>> type(A)
<type 'iterator'>
>>> dir(A)
['__class__', ... ..., '__iter__', ... ..., 'next']
>>> A.next()
'A'
>>> A.next()
'd'
>>> A.next()
's'
>>> A.next()
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration iterator
Any object that implements the __next__
no-argument method which returns the
next item in a series, or raises StopItera
tion when there are no more items. Python
iterators also implement the __iter__
method so they are also iterable. Classic
iterators, according to the original design
pattern, return items from a collection. A
generator is also an iterator, but it’s more
flexible. See generator iterable 可迭代,
一个对象,如果该对象可以通过内置方法 'iter' 获得可以个 'iterator',则称该对象是可迭代对象 'iterable'
如,
>>> A = iter('ABCCcvsds')
>>> A
<iterator object at 0x00000000036D7320>
>>> type(A)
<type 'iterator'> 一个可迭代对象 'iterable object' 可以用于 循环'loops', 列表推导'comprehensions', 元祖拆包'tuple unpacking'.
实现了 __iter__ 方法, 返回迭代器'iterator'的对象是可迭代的对象'iterable'. 序列'sequences' 是可迭代对象.
实现了 __getitem__ 方法的对象也有可能是可迭代对象. iterable
Any object from which the iter built-in
function can obtain an iterator. An iterable
object works as the source of items in for
loops, comprehensions and tuple unpack‐
ing. Objects implementing an __iter__
method returning an iterator are iterable.
Sequences are always iterable; other objects
implementing a __getitem__ method may
also be iterable. iterable unpacking 可迭代对象拆包
与元祖拆白 'tuple unpacking' 同义. 应用于 'parallel assignment'.
例,
>>> a = (1,2)
>>> b,c = a
>>> a
(1, 2)
>>> b
1
>>> c
2
>>> c,b = b,c
>>> a
(1, 2)
>>> b
2
>>> c
1 parallel assignment
Assigning to several variables from items in
an iterable, using syntax like a, b = [c,
d] — also known as destructuring assign‐
ment. This is a common application of tuple
unpacking. 进一步了解一下儿迭代器对象 'Iterator Objects' 和 'Iterator Protocol',
Iterator Objects
python 中有两种 迭代器对象 'iterator objects'. 一种是 序列迭代器 'sequence iterator', 用于对'序列对象' __getitem__ 方法的支持. 另一种是,上例子中常见的迭代器: 一个可调用对象'callable object', 在其上调用 next()
方法, 依次放回序列中的元素, 迭代结束的时候返回 StopIteration error(sentinel value). 迭代器相关源码,
与'第一种'迭代器相关,
PyTypeObject PySeqIter_Type
python 类型对象-'PySeqIter_Type' 为迭代器对象的'类型对象', 由 PySeqIter_New() 函数产生.
也是通过 iter(iterable) 内建函数所得到'序列'的类型对象. int PySeqIter_Check(op)
当 op 是 PySeqIter_Type 类型的时候, 函数返回 true PyObject* PySeqIter_New(PyObject *seq)
创建一个迭代器对象, 迭代结束后 raises IndexError 与'另一种'迭代器相关,
PyTypeObject PyCallIter_Type
由 PyCallIter_New() 创建的可'指定' sentinel value 的迭代器的类型对象. iter(callable, sentinel value) int PyCallIter_Check(op)
当 op 是 PyCallIter_Type 类型的时候, 函数返回 true PyObject* PyCallIter_New(PyObject *callable, PyObject *sentinel)
创建一个迭代器对象, 迭代返回 sentinel value 结束, 并 raises IndexError
第一个参数是任何 python callable 的对象. 例子,
第一种'迭代器
>>> abc = [1,2,3,"S",4,5]
>>> a = iter(abc)
>>> a
<listiterator object at 0x00000000037E0668>
>>> a.next()
1
>> a.next()
2
>>> a.next()
3
>>> a.next()
'S'
>>> a.next()
4
>>> a.next() # 当迭代器中没有新的数据的时候 StopIteration
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
>>> a # StopIteration 后迭代器对象还存在
<listiterator object at 0x00000000037E0668>
>>> a.next() # 迭代器返回最后一个数据后,如果想再获取其中的元素, 需要再次生成新的迭代器对象
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration 另外一种'迭代器
>>> b = iter(abc.pop, "S") # abc.pop 是一个 callable 的对象, 指定 StopIteration 的值'S'
>>> b
<callable-iterator object at 0x00000000037E0668>
>>> b.next()
4
>>> b.next() # next 方法得到元素 'S', raises StopIteration
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration Iterator Protocol
python 在 C 层面有2个函数跟 迭代器 'iterator' 相关, int PyIter_Check(PyObject *o)
如果 对象 o 支持 迭代器协议 interator protocol 返回 true. PyObject* PyIter_Next(PyObject *o)
返回迭代 'iteration' 的下一个元素.
o 必须是一个迭代器(*** 注意,该函数本身并不对这一点做验证; 有使用者保证传入的是 iterator),
如果没有可以返回的元素, 返回 return NULL (没有exception 描述);
如果在获取元素的时候发生了任何的错误 errors, 返回 return NULL 即相应的 exception 描述. python 官方示例,
PyObject *iterator = PyObject_GetIter(obj);
PyObject *item; if (iterator == NULL) {
/* propagate error */
} while (item = PyIter_Next(iterator)) {
/* do something with item */
...
/* release reference when done */
Py_DECREF(item);
} Py_DECREF(iterator); if (PyErr_Occurred()) {
/* propagate error */
}
else {
/* continue doing useful work */
}
iterator 应用的经典示例,
with open('mydata.txt') as fp:
for line in iter(fp.readline, ''):
process_line(line)
Iterator Protocol - Python 描述符协议的更多相关文章
- 杂项之python描述符协议
杂项之python描述符协议 本节内容 由来 描述符协议概念 类的静态方法及类方法实现原理 类作为装饰器使用 1. 由来 闲来无事去看了看django中的内置分页方法,发现里面用到了类作为装饰器来使用 ...
- Descriptor - Python 描述符协议
描述符(descriptor) descriptor 是一个实现了 __get__. __set__ 和 __delete__ 特殊方法中的一个或多个的. 与 descriptor 有关的几个名词解释 ...
- 【转载】Python 描述符简介
来源:Alex Starostin 链接:www.ibm.com/developerworks/cn/opensource/os-pythondescriptors/ 关于Python@修饰符的文章可 ...
- 一文掌握 Python 的描述符协议
描述符介绍 描述符本质就是一个新式类,在这个新式类中,至少要实现了__get__(),__set__(),__delete__()中的一个.这也被称为描述符协议. class Myclass(obje ...
- python描述符理解
Python中的描述符是一个相对底层的概念 descriptor Any object which defines the methods get(), set(), or delete(). Whe ...
- python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解
1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...
- python描述符descriptor(一)
Python 描述符是一种创建托管属性的方法.每当一个属性被查询时,一个动作就会发生.这个动作默认是get,set或者delete.不过,有时候某个应用可能会有 更多的需求,需要你设计一些更复杂的动作 ...
- Python描述符的使用
Python描述符的使用 前言 作为一位python的使用者,你可能使用python有一段时间了,但是对于python中的描述符却未必使用过,接下来是对描述符使用的介绍 场景介绍 为了引入描述符的使用 ...
- 11.python描述符---类的装饰器---@property
描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...
随机推荐
- Ubuntu 设置中文输入法
环境:新安装的Ubuntu 16.04 LTS 本来打算使用sogou拼音,但是在输入后的提示框中内容为乱码,因此尝试重新安装. 1.sudo apt-get remove sogoupinyin & ...
- [bzoj4446] [loj#2009] [Scoi2015] 小凸玩密室
Description 小凸和小方相约玩密室逃脱,这个密室是一棵有 \(n\) 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 \(Ai\) ,每条边也有个权值 \ ...
- tensorboard网络结构
一.tensorboard网络结构 import tensorflow as tffrom tensorflow.examples.tutorials.mnist import input_data ...
- 【原创】(一)Linux进程调度器-基础
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- 19_07_08校内训练[grid]
题意 现有n*m的长方形网格,每个格子中写着一个数,并构成了[0,n*m)的排列.每次可以将一行循环平移x格,也可以将一列循环平移x格.给出初始状态,给出一个到达给定状态的方案.n*m<=100 ...
- webapi的cors配置
NuGet搜索 cors,安装如图显示的: 一.全局配置 在App_Start文件夹的WebApiConfig.cs中加入代码 EnableCorsAttribute cors = new Enabl ...
- [HAOI2015]树上操作(树链剖分)
[HAOI2015]树上操作(luogu) Description 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增 ...
- Map梳理
Map梳理 类型介绍 通用Map:用于在应用程序中管理映射,通常在 java.util 程序包中实现 HashMap.Hashtable.Properties.LinkedHashMap.Identi ...
- Warshall算法求传递闭包及具体实现
传递闭包 在数学中,在集合 X 上的二元关系 R 的传递闭包是包含 R 的 X 上的最小的传递关系. 例如,如果 X 是(生或死)人的集合而 R 是关系“为父子”,则 R 的传递闭包是关系“x 是 y ...
- mybatis typeAlias (别名)说明
...