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 ...
随机推荐
- 【ARM-Linux开发】Linux内存管理:ARM Memory Layout以及mmu配置
原文:Linux内存管理:ARM Memory Layout以及mmu配置 在内核进行page初始化以及mmu配置之前,首先需要知道整个memory map. 1. ARM Memory Layout ...
- [学习笔记] 在Eclipse中导出可以直接运行的jar,依赖的jar打在jar包中
本文需要参考前文: [学习笔记] 在Eclipse中导出可以直接运行的jar,依赖的jar在子目录中 上文是导出的运行的依赖jar被放在了子目录中,本文是将依赖jar放在可运行jar的本身,这样发布的 ...
- Mybatis插件之Mybatis-Plus的CRUD方法
使用Mybatis-plus进行基本的CRUD(增查改删)操作. 实体类(User)代码: import com.baomidou.mybatisplus.annotation.IdType; imp ...
- 处理vue页面406问题纪要
1.servlet-mapping url-pattern / 与 /* 的区别注意关注 2.mvc:resource 是否生效,注意关注,如不生效,可在 web.xml中配置<servlet- ...
- Java网络编程面试总结
转载. https://blog.csdn.net/qq_39470733/article/details/84635274 1.GET 和 POST 的区别? GET 请求可被缓存 GET 请求保留 ...
- 1.4Zookeeper和Thymeleaf的使用
什么是Zookeeper? Zookeeper 是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务.配置维护和命名服务等等.采用下图描述zookeep ...
- (八)Spring 事务管理
目录 文章目录 @[toc] **`Spring`** 事务管理 `Api` 介绍之 **`PlatformTransactionManager`** 后记 #Spring 的事务管理 编程式事务管理 ...
- 2019.08.02 云从科技C++后台开发
公司坐标:重庆 岗位:C++后台开发 面试时长:45分钟 主要问题记录: (1)手写代码 冒泡算法的实现: /** * 冒泡排序:C++ * * @author skywang * @ ...
- Pots(POJ-3414)【BFS】
题意:有两个有着固定容量的茶壶,初始时都为空,要求用FILL,POUR,DROP三种操作来准确地得到C值,输出最少次数及操作方案. 思路:比赛的时候真是脑子不好使,根本没想到是搜索,看了别人的题解用搜 ...
- 怎样理解AJAX
AJAX: Asynchronous JavaScript and XML, 翻译过来就是: 异步的JavaScript与XML 这已经成为了一个通用名词, 字面意义已经消失了, 因为现在使用Java ...