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):__ ...
随机推荐
- 【转】最受欢迎的8位Java牛人
本文由 ImportNew - 唐尤华 翻译自 javatyro.如需转载本文,请先参见文章末尾处的转载要求. 下面是8位Java牛人,他们为Java社区编写框架.产品.工具或撰写书籍改变了Java编 ...
- 值得收藏!my.cnf配置文档详解
MySql对于开发人员来说应该都比较熟悉,不管是小白还是老码农应该都能熟练使用.但是要说到的各种参数的配置,我敢说大部分人并不是很熟悉,当我们需要优化mysql,改变某项参数的时候.还是要到处在网上查 ...
- 【5min+】闪电光速拳? .NetCore 中的Span
系列介绍 简介 [五分钟的DotNet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的. ...
- H5录音音频可视化-实时波形频谱绘制、频率直方图
这段时间给GitHub Recorder开源库添加了两个新的音频可视化功能,比以前单一的动态波形显示丰富了好多(下图后两行是不是比第一行看起来丰满些):趁热打铁写了一个音频可视化相关扩展测试代码,下面 ...
- java类中元素初始化顺序
结论:对于静态变量.静态初始化块.变量.初始化块.构造器,它们的初始化顺序依次是(静态变量.静态初始化块)>(变量.初始化块)>构造器. public class Test4 { @Tes ...
- Java入门 - 语言基础 - 09.循环结构
原文地址:http://www.work100.net/training/java-loop.html 更多教程:光束云 - 免费课程 循环结构 序号 文内章节 视频 1 概述 2 while循环 3 ...
- P2869 [USACO07DEC]美食的食草动物Gourmet Grazers
P2869 [USACO07DEC]美食的食草动物Gourmet Grazers 题目:约翰的奶牛对食物越来越挑剔了.现在,商店有M 份牧草可供出售,奶牛食量很大,每份牧草仅能供一头奶牛食用.第i 份 ...
- 最新Pyecharts-基本图表
Pyecharts是由Echarts而来,Echarts是百度开源的数据可视化的库,适合用来做图表设计开发,当使用Python与Echarts结合时就产生了Pyecharts.可使用pip安装,默认是 ...
- Arrays.asList()用法梳理
Arrays.asList()用法梳理 asList概述 Arrays是java容器相关操作的工具类,asList方法将Array转换为list,是Array和List之间的桥梁. asList本质 ...
- AOP编程实践总结
AOP编程实践总结 AOP概述 AOP(Aspect-Oriented Programming,面向方面编程)是OOP(Object-Oriented Programing,面向对象编程)的补充和完善 ...