Python - 三大器 迭代器,生层器,装饰器
Python - 三大器 迭代器,生层器,装饰器
在介绍三大器之前先来了解一下容器和可迭代对象...
一. 容器
容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有:
- list, deque...
- set, frozensets(不可变集合)...
- dict, defaultdict, OrderedDict, Counter...
- tuple, namedtuple...
- str
容器的概念就像一个盒子,可以往里面装东西.当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,set,tuples都是容器对象:
>>> assert 1 in [1, 2, 3] # lists
>>> assert 4 not in [1, 2, 3]
>>> assert 1 in {1, 2, 3} # sets
>>> assert 4 not in {1, 2, 3}
>>> assert 1 in (1, 2, 3) # tuples
>>> assert 4 not in (1, 2, 3)
询问某元素是否在dict中用dict的中key:
>>> d = {1: 'foo', 2: 'bar', 3: 'qux'}
>>> assert 1 in d
>>> assert 'foo' not in d # 'foo' 不是dict中的元素
询问某substring是否在string中:
>>> s = 'foobar'
>>> assert 'b' in s
>>> assert 'x' not in s
>>> assert 'foo' in s
尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力,当然并不是所有的容器都是可迭代的,比如:Bloom filter,虽然Bloom filter可以用来检测某个元素是否包含在容器中,但是并不能从容器中获取其中的每一个值,因为Bloom filter压根就没把元素存储在容器中,而是通过一个散列函数映射成一个值保存在数组中。
二. 可迭代对象(iterable)
大部分对象都是可迭代,只要实现了__iter__方法的对象就是可迭代的。
__iter__方法会返回迭代器(iterator)本身,例如:
>>> lst = [1,2,3]
>>> lst.__iter__()
<listiterator object at 0x7f97c549aa50>
Python提供一些语句和关键字用于访问可迭代对象的元素,比如for循环、列表解析、逻辑操作符等。
判断一个对象是否是可迭代对象:
>>> from collections import Iterable # 只导入Iterable方法
>>> isinstance('abc', Iterable)
True
>>> isinstance(1, Iterable)
False
>>> isinstance([], Iterable)
True
这里的isinstance()函数用于判断对象类型。
可迭代对象一般都用for循环遍历元素,也就是能用for循环的对象都可称为可迭代对象。
例如,遍历列表:
>>> lst = [1, 2, 3]
>>> for i in lst:
... print i
...
三. 迭代器
迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退)
实现了迭代器协议的对象(对象内部定义了一个__iter__()方法)
python中的内部工具(如for循环,sum,min,max函数等)基于迭代器协议访问对象。
使用迭代器的好处:
1)如果使用列表,计算值时会一次获取所有值,那么就会占用更多的内存。而迭代器则是一个接一个计算。
2)使代码更通用、更简单。
判断是否是迭代器:
>>> from collections import Iterator
>>> isinstance(d, Iterator)
False
>>> isinstance(d.iteritems(), Iterator)
True
使用next方法:
>>> iter_items = d.iteritems()
>>> iter_items.next()
('a', 1)
>>> iter_items.next()
('c', 3)
>>> iter_items.next()
('b', 2)
迭代器的原理:
1 #基于迭代器协议
2 li = [1,2,3]
3 diedai_l = li.__iter__()
4 print(diedai_l.__next__())
5 print(diedai_l.__next__())
6 print(diedai_l.__next__())
7 # print(diedai_l.__next__()) # 超出边界报错
8
9 #下标
10 print(li[0])
11 print(li[1])
12 print(li[2])
13 # print(li[3]) # 超出边境报错
14
15 # 用while循环模拟for循环机制
16 diedai_l = li.__iter__()
17 while True:
18 try:
19 print(diedai_l.__next__())
20 except StopIteration:
21 print("迭代完毕,循环终止")
22 break
23
24 # for循环访问方式
25 # for循环本质就是遵循迭代器协议的访问方式,先调用diedai_l=li.__iter__方法
26 # 或者直接diedai_l=iter(l),然后依次执行diedai_l.__next__(),直到捕捉到
27 # StopItearation终止循环
28 # for循环所有的对象的本质都是一样的原理
四. 生成器
可以理解为一种数据类型,自动实现迭代器协议
在调用生成器运行的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行next()方法时从当前位置继续运行
表现形式:
生成器函数 带yield的函数(1、返回值 2、保留函数的运行状态)
next(t) t.__next__ t.send(可以给上一层的yield传值)
# 用生成器函数
# yield 相当于return控制的是函数的返回值
# x=yield的另外一个特性,接收send传过来的值,赋值给x
def test():
print("开始啦")
first = yield # return 1 first = None
print("第一次",first)
yield 2
print("第二次")
t = test()
print(test().__next__())
res = t.__next__() # next(t)
print(res)
res = t.send("函数停留在first那个位置,我就是给first赋值的")
print(res) 输出结果
开始啦
None
开始啦
None
第一次 函数停留在first那个位置,我就是给first赋值的
生成器表达式
print(sum(i for i in range(10000))) # 表达式一般用for循环 (i for i in range(10000))
作用 节省内存,在内部已经实现了__iter__的方法
五. 装饰器
1. 定义
在不修改被修饰函数的源代码和调用方式的情况下给其添加额外功能.
装饰器 = 高阶函数+函数嵌套+闭包
import time #导入时间模块
def foo(func): # func = test
def bar(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs) # 这里就是在运行test() 赋予变量
stop_time = time.tiem()
print("一场LOL时间为{}").format(stop_time-start_time)
return res # 返回test()的值
return bar
def test(name, age):
time.sleep(1)
print("哈哈")
return "heihei"
res = test("德玛西亚", age=10)
print(ret)
六. 闭包
根据这句话,其实我们自己就可以总结出在python语言中形成闭包的三个条件,缺一不可:
1)必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套
2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量
3)外部函数必须返回内嵌函数——必须返回那个内部函数
def funx():
x=5
def funy():
nonlocal x
x+=1
return x
return funy
python闭包的优点:
避免使用全局变量
可以提供部分数据的隐藏
可以提供更优雅的面向对象实现
Python - 三大器 迭代器,生层器,装饰器的更多相关文章
- 详解python三大器——迭代器、生成器、装饰器
迭代器 聊迭代器前我们要先清楚迭代的概念:通常来讲从一个对象中依次取出数据,这个过程叫做遍历,这个手段称为迭代(重复执行某一段代码块,并将每一次迭代得到的结果作为下一次迭代的初始值). 可迭代对象(i ...
- Python 闭包、迭代器、生成器、装饰器
Python 闭包.迭代器.生成器.装饰器 一.闭包 闭包:闭包就是内层函数对外层函数局部变量的引用. def func(): a = "哈哈" def func2(): prin ...
- python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器
1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...
- python 生成器,迭代器,闭包,装饰器
1.生成器,迭代器,闭包,装饰器的优点 生成器就是一类特殊的迭代器 迭代器的优点也即生成器的优点: 1.节约内存.python在使用生成器时对延迟操作提供了支持. 2.迭代到下一次的调用时,所使用的参 ...
- python基础之迭代器、生成器、装饰器
一.列表生成式 a = [0,1,2,3,4,5,6,7,8,9] b = [] for i in a: b.append(i+1) print(b) a = b print(a) --------- ...
- python基础知识---迭代器、生成器、装饰器
一.迭代器 二.生成器 http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html def func(): #定义生成器,和普通函数的区别是 ...
- Python学习(三):迭代器、生成器、装饰器、递归、算法、正则
1.迭代器 迭代器是访问集合的一种方式,迭代对象从集合的第一个元素开始访问,直到元素被访问结束,迭代器只能往前不能后退,最大的优点是不要求事先准备好整个迭代过程中的元素,这个特点使得它特别适合用于遍历 ...
- Python开发——7.迭代器、生成器和装饰器
一.迭代器 1.迭代器协议 (1)迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么引起一个StopIteration移除异常以中止迭代. (2)可迭代对象:实现了迭 ...
- Python基础4 迭代器,生成器,装饰器,Json和pickle 数据序列化
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
随机推荐
- 【Aladdin Unity3D Shader编程】之二 光照模型(一)
光照模型 光照模型就是一个公式,使用这个公式来计算在某个点的光照效果. 在标准光照模型里面,我们把进入摄像机的光分为下面四个部分: 自发光 类似生活中的萤火虫等自己能够发光 高光反射 类似生活中的镜子 ...
- 【bzoj1207】[HNOI2004]打鼹鼠
看了数据范围,想想这不暴力可以过?? DP #include<algorithm> #include<iostream> #include<cstdlib> ...
- 【转】Andorid获取状态栏高度
在应用开发中,有时我们需要用代码计算布局的高度,可能需要减去状态栏(status bar)的高度.状态栏高度定义在Android系统尺寸资源中status_bar_height,但这并不是公开可直接使 ...
- WPF-使用面板控制内容布局,比较Canvas,WrapPanel,StackPanel,Grid,ScrollViewer
WPF-使用面板控制内容布局,比较Canvas,WrapPanel,StackPanel,Grid,ScrollViewer 分类: WPF2012-04-24 09:59 660人阅读 评论(0) ...
- C#的内存管理知识 .
本章介绍内存管理和内存访问的各个方面.尽管运行库负责为程序员处理大部分内存管理工作,但程序员仍必须理解内存管理的工作原理,了解如何处理未托管的资源. 如果很好地理解了内存管理和C#提供的指针功能,也就 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
- JSP-Runoob:JSP 状态码
ylbtech-JSP-Runoob:JSP 状态码 1.返回顶部 1. SP HTTP 状态码 HTTP请求与HTTP响应的格式相近,都有着如下结构: 以状态行+CRLF(回车换行)开始 零行或多行 ...
- JSP-Runoob:JSP 调试
ylbtech-JSP-Runoob:JSP 调试 1.返回顶部 1. JSP 调试 要测试/调试一个JSP或servlet程序总是那么的难.JSP和Servlets程序趋向于牵涉到大量客户端/服务器 ...
- Vue组件库elementUI 在el-row 或 el-col 上使用@click无效失效,
问题: elementUI 在el-row 或者 el-col 上使用@click失效, 解决: 在click后面加上 .native .要使用@click.native=”handler()”才行, ...
- Aspose Cells dll 实现数据简单下载
Workbook workbook = new Workbook(); //工作簿 Worksheet sheet = workbook.Worksheets[ ...