迭代器

首先我们查看下列类型拥有的所有方法(会显示很多)

print(dir([]))
print(dir({}))
print(dir(''))
print(dir(range(10)))
#求下上面列表中方法的交集
ret = set(dir([]))&set(dir({}))&set(dir(''))&set(dir(range(10))) #set 转化为列表
print(ret) #可以注意到都有这两个双下方法
# __init__ __iter__ #我们来举一个双下方法的例子
#举例:列表的相加 print([1].__add__([2]))
print([1]+[2]) #实际执行的是 print([1].__add__([2])) #接着我来看一下 int 类型
for i in 123:
print(i) #不可被循环的会提示该报错:TypeError: 'int' object is not iterable(iterable:可迭代的)
#原因是 int 类型没有该方法 __iter__

判断数据类型中是否有 __iter__ 方法

print('__iter__' in dir(int))   #False
print('__iter__' in dir(bool))  #False
print('__iter__' in dir(list))
print('__iter__' in dir(dict))
print('__iter__' in dir(set))
print('__iter__' in dir(tuple))
print('__iter__' in dir(enumerate([])))
print('__iter__' in dir(range(1))) #方法之间也可以相减 去重(主要是查看 并没有什么用)
print(set(dir([].__iter__())) - set(dir([])))

只要是能被 for 循环的数据类型 就一定拥有 __iter__ 方法,一个列表执行了 __iter__() 之后的返回值就是一个迭代器

print([].__iter__())
<list_iterator object at 0x0000000000A8F2E8> #iterator 迭代器,返回的是一个内存地址
#使用 __next__ 一个一个的取值
l = [1,2,3]
iterator = l.__iter__()
print(iterator)    #列表是可以迭代的,当可迭代的后面加上 .__iter__() 方法,就可以得到一个迭代器,返回是一个内存地址
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__()) #当无值可取时会抛出 StopIteration 的异常
print(iterator.__next__()) #for 循环就是一个迭代器 当无值可取时也会出现该异常,但是 for 已经帮我们处理了 #__length_hint__ 计算元素个数
print([1,'a','bbb'].__iter__().__length_hint__())

Iterable 可迭代的    ——>  __iter__  只要含有 __iter__ 方法的都是可迭代的 —— 可迭代协议
[].__iter__() 迭代器 ——>  __next__   通过 next 就可以从迭代器中一个一个的取值

简单的证明一下上面的结论

from collections import Iterable
from collections import Iterator class A:
def __iter__(self):pass #在这两处添加注释 然后查看下面的输出结果
def __next__(self):pass #两次查看做下对比 a = A()
print(isinstance(a,Iterator))
print(isinstance(a,Iterable))

迭代器的概念

迭代器协议 —— 内部含有 __next__ 和 __iter__ 方法的就是迭代器

迭代器协议和可迭代协议

要含有 __iter__ 方法的都是可迭代的 —— 可迭代协议
部含有 __next__ 和 __iter__ 方法的就是迭代器 —— 迭代器协议
可以被for循环的都是可迭代的
可迭代的内部都有 __iter__ 方法
只要是迭代器,一定是可迭代的
可迭代的 .__iter__() 方法就可以得到一个迭代器
迭代器中的 __next__() 方法可以一个一个的获取值

for 循环

for 循环其实就是在使用迭代器

只有 是可迭代对象的时候 才能用 for
当我们遇到一个新的变量,不确定能不能 for 循环的时候,就判断它是否可迭代(判断它内部有没有 __iter__ )

for 循环的运行逻辑

for i in l:
pass
iterator = l.__iter__()
iterator.__next__()

迭代器的好处

从容器类型中一个一个的取值,会把所有的值都取到。
节省内存空间(因为它不是一下子发内容存到内存当中的,而是一条一条的读取)
迭代器并不会在内存中再占用一大块内存,
而是随着循环 每次生成一个
每次 next 每次给我一个

装饰器复习

装饰器
装饰器的作用:在不改变原来函数的调用方式的情况下,在这个函数的前后添加新的功能
完美的符合了一个开发原则:开放封闭原则
  对扩展的是开放的
  对修改是封闭的

基础的装饰器

from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs):
'''在函数被调用之前添加的代码'''
ret = func(*args,**kwargs) # func是被装饰的函数 在这里被调用
'''在函数被调用之后添加的代码'''
return ret
return inner
#使用 —— @wrapper
@wrapper
def func(): #inner
pass

带参数的装饰器

@wrapper -- > @warapper(argument)
#三层嵌套函数
def outer(形参):
def wrapper(func):
def inner(*args,**kwargs):
'''在函数被调用之前添加的代码'''
ret = func(*args,**kwargs) # func是被装饰的函数 在这里被调用
'''在函数被调用之后添加的代码'''
return ret
return inner
return wrapper @outer(True)
def func():
pass

多个装饰器装饰一个函数

from functools import wraps
def wrapper1(func):
@wraps(func)
def inner(*args,**kwargs):
print('before 1')
print('******')
ret = func(*args,**kwargs) # func是被装饰的函数 在这里被调用
'''在函数被调用之后添加的代码'''
return ret
return inner def wrapper2(func):
@wraps(func)
def inner(*args,**kwargs):
print('before 2')
ret = func(*args,**kwargs) # func是被装饰的函数 在这里被调用
'''在函数被调用之后添加的代码'''
return ret
return inner @wrapper1
@wrapper2
def func():
print('') func()

day 13 - 1 迭代器的更多相关文章

  1. Java描述设计模式(13):迭代器模式

    本文源码:GitHub·点这里 || GitEE·点这里 一.迭代器模式 1.基础概念 迭代器模式又叫游标模式,是对象的行为模式.迭代器模式可以顺序地访问一个聚集中的元素而不必暴露聚集的内部表象. 2 ...

  2. 把《c++ primer》读薄(3-2 标准库vector容器+迭代器初探)

    督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 标准库vector类型初探,同一种类型的对象的集合(类似数组),是一个类模版而不是数据类型,学名容器,负责管理 和 存储的元素 ...

  3. C语言字符串操作总结大全

    1)字符串操作 strcpy(p, p1)  复制字符串  函数原型strncpy(p, p1, n)   复制指定长度字符串  函数原型strcat(p, p1)   附加字符串  函数原型strn ...

  4. C语言字符串操作总结大全(超详细)

    本篇文章是对C语言字符串操作进行了详细的总结分析,需要的朋友参考下 1)字符串操作  strcpy(p, p1) 复制字符串  strncpy(p, p1, n) 复制指定长度字符串  strcat( ...

  5. c语言的字符串操作(比较详细)

    1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...

  6. PHP Predefined Interfaces 预定义接口(转)

    SPL提供了6个迭代器接口: Traversable 遍历接口(检测一个类是否可以使用 foreach 进行遍历的接口) Iterator 迭代器接口(可在内部迭代自己的外部迭代器或类的接口) Ite ...

  7. 重拾C++ 基础知识总结(二)

    1.标准库string类型: 用户程序要使用string类型对象,必须包含相关头文件 #include <string> 字符串字面值与标准库string类型不是同一种类型,字符串字面值是 ...

  8. Boost程序库完全开发指南——深入C++“准”标准库(第3版)

    内容简介  · · · · · · Boost 是一个功能强大.构造精巧.跨平台.开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉. Boost 由C++标准委员会部分成员所设立的Bo ...

  9. C语言字符串操作函数集

    1)字符串操作 strcpy(p, p1) 复制字符串 strncpy(p, p1, n) 复制指定长度字符串 strcat(p, p1) 附加字符串 strncat(p, p1, n) 附加指定长度 ...

随机推荐

  1. Python爬虫 爬取百合网的女人们和男人们

    学Python也有段时间了,目前学到了Python的类.个人感觉Python的类不应称之为类,而应称之为数据类型,只是数据类型而已!只是数据类型而已!只是数据类型而已!重要的事情说三篇. 据书上说一个 ...

  2. DependencyInjection源码解读之ServiceProvider

    var services = new ServiceCollection(); var _serviceProvider = services.BuildServiceProvider(); serv ...

  3. 追逐心目中的那个Ta

    申明:全篇皆为作者臆想,浪漫主义代表派作品,若有雷同,纯属巧合 人生最难过的不就是在一无所有的年纪里遇到了最想呵护一生的人,而在拥有一切的时候却失去了不顾一切的心. 长夜漫漫,本是相思人,偏听多情曲, ...

  4. 在OSGI容器Equinox中嵌入HttpServer

    原文地址:https://liugang594.iteye.com/blog/1328050 简单介绍一下如何在一个osgi的bundle中内嵌使用http服务 一.基础 首先看看在OSGI中怎么启动 ...

  5. 小小知识点(三)——MATLAB如何把三维图用二维图表示

    MATLAB程序: x=-1:0.1:1; [x y] = meshgrid(x); %grid data = load("filename.txt"); figure mesh( ...

  6. photoshop快速把新照片制作成老照片教学

    原图 步骤1 在photoshop中找开需要处理的图片,Ctrl+J复制图片,得到图片1. 步骤2 单击图层面板底部的创建新的填充或调整图层图标,添加色调/饱和度调整图层.调整它的饱合度和明度. 步骤 ...

  7. 阿里云 轻量应用服务器(LAMP) 使用日志记录

    phpStudy(PHP运行环境一键安装包) https://www.jb51.net/softs/182860.html 0:PHP开发工具 https://netbeans.org/downloa ...

  8. mpvue-Vant Weapp踩坑记

    微信开发者工具:开发.调试和模拟运行微信小程序的最核心的工具了,所以必须安装 # 全局安装 vue-cli $ npm install --global vue-cli # 创建一个基于 mpvue- ...

  9. 【zabbix教程系列】二、zabbix特点

    一.度量收集 从任何设备,系统,应用上收集指标,收集指标的方法有: 多平台zabbix代理 SNMP and IPMI 代理 无代理监控用户服务 自定义方法 计算和聚合 用户端web监控  二.问题发 ...

  10. CodeForces 280B Maximum Xor Se

    题目链接:http://codeforces.com/contest/280/problem/B 题目大意: 给定一个由n个数组成的一个序列,s[l..r] (1 ≤ l < r ≤ n)代表原 ...