python3:iterable, iterator, generator,抽象基类, itertools的使用。
目录:
iterable对象
iterator对象, 数据类型Iterator类
数据类型Generator类。
生成器表达式
collections.abc:容器的抽象基类。用于判断具体类。
itertools模块:很多生成iterator的函数。
延伸:duck-typing:理解python动态语言;再看继承和多态
iterable -- 可迭代对象
能够逐一返回其成员项的对象。包括:
- 有序类型list, str, tuple
- 无序类型dict, set
- 任何定义了__iter__, __next__的类的对象。
可迭代对象被可用于 for 循环以及许多其他需要一个序列的地方(zip()、map() ...)。
当一个可迭代对象作为参数传给内置函数 iter() 时,它会返回该对象的迭代器。这种iterator适用于对值集合的一次性遍历。
例子:
>>> a = [1, 2, None]
>>> a
[1, 2, None]
>>> iter(a)
<list_iterator object at 0x106a28f10>
for语句会自动为可迭代对象创建一个的迭代器。用于循环期间的操作。
iterator -- 迭代器
用来表示一连串数据流的对象。重复调用迭代器的 __next__() 方法(或将其传给内置函数 next())将逐个返回流中的项。
大多数容器对象都可以使用for循环语句:
这幕后的机制就是,for循环内部使用了iter(), 为容器对象生成一个iterator对象。这个对象使用__next__()来逐一输出容器对象内的数据。
数据类型--Iterator类型
即对容器对象提供迭代的支持。
container.__iter__()
返回一个iterator对象。它有2个方法:
- iterator.__iter__(): 返回自身,用于配合for和in语句。
- iterator.__next__(): 从容器中返回下一项item。
Python定义了几种iterator对象,用于对序列类型list,str,tuple,字典dict, 和其他特别的形式进行迭代操作。
数据类型--generator类型
generator提供了实现迭代器的快捷方法。
⚠️:根据抽象基类: Generator继承自Iterator。但只是抽象的。
方法:
定义一个函数,在内部使用yield,这个函数就是一个generator函数,它是函数对象。类是<class function>。
用它创建的对象,就是生成器对象。generator 对象。reverse(10).__class__是<class 'generator'>
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index] >>> for char in reverse('golf'):
... print(char)
...
f
l
o
g
生成器表达式:
一个更简便的方法定义generator。
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
>>> next(g)
0
>>> next(g)
1
每调用一次next,就是循环一次。
例子,演示定义一个生成可迭代对象的类:
#linshi.py
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data) def __iter__(self):
return self def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
然后:
>>> import linshi.py
>>> import linshi
>>> rev = linshi.Reverse('spam')
>>> rev
<linshi.Reverse object at 0x107c01430>
>>> from collections.abc import Iterable
>>> isinstance(rev, Iterable)
True
由此可知,定义的rev类的对象是可迭代的对象。
collections.abc ---容器的抽象基类
这个模块定义了一些抽象基类。它们可用于判断一个具体类是否具有某一特定的接口;例如,这个类是否可哈希,或其是否为映射类。
abc是abstract base class的简写。是鸭子类型duck-typing的补充。
ABC 引入了虚拟子类,这种类并非继承自其他类,但却仍能被 isinstance() 和 issubclass() 所认可;详见 abc 模块文档。

class collections.abc.Iterable
使用 isinstance(obj, Iterable) 可以检测一个类是否已经注册到了 Iterable 或者实现了 __iter__() 函数。
例子:
>>> from collections.abc import Iterator
>>> isinstance([1,2], Iterable)
True
list实例并非继承自collections.abc.Iterable类。但是Iterable类是一个抽象基类。它提供了接口,用于判断list是否可迭代。
listl类有__iter__方法, 因此可以判断它是可迭代的。
itertools模块
itertools 模块中主要包含了一些用于生成迭代器的函数。
例子:
>>> import collections.abc as abc
>>> import itertools as it
>>> it.count
<class 'itertools.count'>
>>> a = it.count(10.3)
>>> a
count(10.3)
>>> abc.Iterable
<class 'collections.abc.Iterable'>
>>> isinstance(a, abc.Iterable)
True
>>> isinstance(a, abc.Iterator)
True
解释:使用count()生成的对象a是可迭代的,同时也是迭代器。
itertools模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是Iterator,只有用for循环迭代的时候才真正计算。
(延伸)duck-typing
指一种编程风格,它并不依靠查找对象类型来确定其是否具有正确的接口,而是直接调用或使用其方法或属性。
“看起来像鸭子,叫起来也像鸭子,那么肯定就是鸭子。”
由于强调接口而非特定的类型,设计良好的代码可通过允许"多态替代"polymorphic substitution来提升灵活性。
高级的动态语言都有这种编程风格,这和静态语言如java是不一样的。(摘录:Ruby元编程P116)
在静态语言里,说对象的类型是T,是因为它属于T类(或是因为它实现了接口T),而在Ruby这样的动态语言,对象的"类型"并不严格的和它的类相关,"类型"只是对象能相应的一组方法。这种概念就是duck-typing。
duck-typing编程风格可以归类到多态中去。
例子:
class Eg1:
def __init__(self, text):
self.text = text
self.sub_text = text.split(' ')
def __getitem__(self, index):
return self.sub_text[index]
def __len__(self):
return len(self.sub_text)
o1 = Eg1('Hello, the wonderful new world!')
print('长度:', len(o1))
for i in o1:
print(i)
类Eg1。它的对象可以计算长度,可以循环,这是因为它通过object.__len__, object.__getitem__实现了相应的协议。这种无需关注它的类型,而只注重接口的编码风格,就是duck-typing。
本例子:通过在类中定义了__getitem__方法,实例o1可以:
- 做取值运算,o1[0], []就是一个语法糖。相当于调用o1.__getitem(0),或type(o1).__getitem__(o1, 0)
- 通过__getitem__,让o1支持序列协议sequence protocol。 可以使用iter(object)方法。
⚠️,实现了__getitem__和__len__就会被认为是序列。
继承和多态
例子:
动物->鸭子,鸭子可以分为绿头鸭,黄鸭等等。这是继承。
一只黄鸭的类型是黄鸭,它也是鸭子,也是动物。
多态:
对于一个实例对象,开发者只需要知道它是鸭子类型,就可以使用鸭子类型的各种实例方法,比如swimming()方法。无需知道它的子类型,即是黄鸭还是绿头鸭的问题。
只有在运行代码时,后台代码才会自动判断它是什么子类型,然后沿着继承链条,找到鸭子类中的实例方法。
重写方法:
父类鸭子类,有swimming()方法,绿头鸭类,可以在自身重写swimming()方法,这样绿头鸭的实例就只会调用绿头鸭类的swimming()方法。当然可以在这个方法内使用super调用父类的swimming()方法,并对其修改。形成自身的swimming方法。
python3:iterable, iterator, generator,抽象基类, itertools的使用。的更多相关文章
- python(七):元类与抽象基类
一.实例创建 在创建实例时,调用__new__方法和__init__方法,这两个方法在没有定义时,是自动调用了object来实现的.python3默认创建的类是继承了object. class A(o ...
- guxh的python笔记七:抽象基类
1,鸭子类型和白鹅类型 1.1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__ ...
- 【Python】【元编程】【从协议到抽象基类】
"""class Vector2d: typecode = 'd' def __init__(self,x,y): self.__x = float(x) self.__ ...
- python面对对象编程---------6:抽象基类
抽象基本类的几大特点: 1:要定义但是并不完整的实现所有方法 2:基本的意思是作为父类 3:父类需要明确表示出那些方法的特征,这样在写子类时更加简单明白 用抽象基本类的地方: 1:用作父类 2:用作检 ...
- PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)
前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...
- Python中的抽象基类
1.说在前头 "抽象基类"这个词可能听着比较"深奥",其实"基类"就是"父类","抽象"就是&quo ...
- Python抽象基类:ABC谢谢你,因为有你,温暖了四季!
Python抽象基类:ABC谢谢你,因为有你,温暖了四季! Python抽象基类:ABC谢谢你,因为有你,温暖了四季! 实例方法.类方法和静态方法 抽象类 具名元组 参考资料 最近阅读了<Pyt ...
- 24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment
24 UsageEnvironment使用环境抽象基类——Live555源码阅读(三)UsageEnvironment 24 UsageEnvironment使用环境抽象基类——Live555源码阅读 ...
- 18 TaskScheduler任务调度器抽象基类——Live555源码阅读(一)任务调度相关类
这是Live555源码阅读的第二部分,包括了任务调度相关的三个类.任务调度是Live555源码中很重要的部分. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/ol ...
随机推荐
- C#实现隐藏手机号、邮箱、姓名等敏感信息扩展方法
还是老惯例,直接上代码. 最终效果图: public static class HideSensitiveInfoExtension { /// <summary> /// 隐藏敏感信息 ...
- jstack使用
top -p 22072 -H -p:查看某个进程 -H列出所有的线程 printf '%x' 22398 (16进制线程号) sudo -u tomcat jstack 22072 | grep ...
- java中volatile关键字的作用
一.内存模型的相关概念 大家都知道,计算机在执行程序时,每条指令都是在CPU中执行的,而执行指令过程中,势必涉及到数据的读取和写入.由于程序运行过程中的临时数据是存放在主存(物理内存)当中的,这时就存 ...
- pytorch API中sgd.py的学习记录
参考:PyTorch与caffe中SGD算法实现的一点小区别 其中公式(3)(4)的符号有问题 变量对应表 程序 参考文章 buf v momentum μ d_p Δf(θ) lr ξ p θ
- Mybatis传递List集合
完整错误如下: org.apache.ibatis.binding.BindingException: Parameter ‘customerIdList’ not found. Available ...
- 正式发布! .NET开发控件集ComponentOne 新版本加入Blazor UI
近期,由葡萄城推出的ComponentOne .NET开发控件集正式发布最新版本! ComponentOne 是一套专注于企业 .NET开发.支持 .NET Core 平台,并完美集成于 Visual ...
- python保留字及其说明
保留字 说 明 and 用于表达式运算,逻辑与操作 as 用于类型转换 assert 断言,用于判断变量或条件表达式的值是否为真 break 中断循环语句的执行 class 用于定义类 con ...
- python pyyaml 使用教程(代码案例)
test.py 内容 # 运行前,请先安装pyyaml模块 # pip3 install -i https://pypi.douban.com/simple/ pyyaml==5.1.1 import ...
- not or and 的优先级是不同的
not or and 的优先级是不同的: not > and > or 请用最快速度说出答案: not 1 or 0 and 1 or 3 and 4 or 5 and 6 or 7 an ...
- 植物大战僵尸:查找植物叠加种植CALL
实验目标:我们都知道植物大战僵尸游戏中植物是不可以叠加种植的,也就是一个格子只能种植一个植物,今天我们将实现一个格子里种植无限多的植物. 我们首先需要找到植物的种植CALL,然后在逐步测试观察功能之间 ...