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):__ ...
随机推荐
- Netty快速入门(10)Reactor与Netty
Reactor模式 Reactor是1995年由道格拉斯提出的一种高性能网络编程模式.由于好多年了,当时的一些概念与现在略有不同,reactor模式在网络编程中是非常重要的,可以说是NIO框架的典型模 ...
- 基于C#的机器学习--垃圾邮件过滤
在这一章,我们将建立一个垃圾邮件过滤分类模型.我们将使用一个包含垃圾邮件和非垃圾邮件的原始电子邮件数据集,并使用它来训练我们的ML模型.我们将开始遵循上一章讨论的开发ML模型的步骤.这将帮助我们理解工 ...
- Java Data类
Date类的概述 java.util,Date 表示日期和时间的类类 Date 表示特定的瞬间,精确到千分之一秒(毫秒) 获取时间原点到当前系统时间经历了多少秒 // 时间原点:1970 年 01 月 ...
- 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- github 关掉邮件通知
- 关于爬虫的日常复习(11)—— 实战:flask+redis维护代理池(to be continue)
- 洛谷 P5424 [USACO19OPEN]Snakes
题目链接 题目描述 传说,数千年前圣帕特里克消灭了哞尔兰所有的蛇.然而,蛇们现在卷土重来了!圣帕特里克节是在每年的3月17日,所以Bessie要用彻底清除哞尔兰所有的蛇来纪念圣帕特里克. Bessie ...
- 解决jar包依赖冲突(idea)
在IDEA状态下查看项目依赖的关系 关系如下图 红色数据jar包冲突 在对应的依赖中出去去冲突依赖
- synchronized的使用
概念: 是利用锁的机制来实现同步的. 锁机制有如下两种特性: 互斥性:即在同一时间只允许一个线程持有某个对象锁,通过这种特性来实现多线程中的协调机制,这样在同一时间只有一个线程对需同步的代码块(复合操 ...
- [UVA1494] Qin Shi Huang's National Road System
题目 戳这里 题解 从今天起我要改邪归正,好好刷题准备联赛! 这是一道经典的最小生成树题目. 枚举每一条边作为道士要修的路,求出包含这条边的最小生成树. 先求出原图的最小生成树. 如果要删的边在最小生 ...