python中的迭代器&&生成器&&装饰器
迭代器iterator
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。
迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件
特点:
访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
不能随机访问集合中的某个值 ,只能从头到尾依次访问
访问到一半时不能往回退
便于循环比较大的数据集合,节省内存
作用:
这个yield的主要效果呢,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。
另外,还可通过yield实现在单线程的情况下实现并发运算的效果
判断一个对象是否是可迭代对象
'''
Created on 2018年1月5日 @author: cq
'''
from collections import Iterable class Obj(object):
pass class Fab(object):
def __init__(self, max):
self.max = max
self.n, self.a, self.b = , , def __iter__(self):
return self def next(self):
if self.n < self.max:
r = self.b
self.a, self.b = self.b, self.a + self.b
self.n = self.n +
return r
raise StopIteration() def main():
print("Python常见对象的可迭代性")
print("abc :%s" % type('abc'))
print("is iterable >>",isinstance('abc',Iterable),"\n")
print("123456 :%s" % type())
print("is iterable >>",isinstance(,Iterable),"\n")
print("[1,2,4,5,6] :%s" % type([,,,,]))
print("is iterable >>",isinstance([,,,,],Iterable),"\n")
print("{1,2,4,5,8,5,5,5,5} :%s" % type({,,,,,,,,}))
print("is iterable >>",isinstance({,,,,,,,,},Iterable),"\n")
print("(1,2,4,5,6,8) :%s" % type((,,,,,)))
print("is iterable >>",isinstance((,,,,,),Iterable),"\n")
print("{'a':1,'b':2} :%s" % type({"a":,"b":}))
print("is iterable >>",isinstance({"a":,"b":},Iterable),"\n")
print("Obj() :%s" % type(Obj()))
print("is iterable >>",isinstance(Obj(),Iterable),"\n")
print("Fab(2) :%s" % type(Fab()))
print("is iterable >>",isinstance(Fab(),Iterable),"\n") if __name__ == '__main__':
main()
# 输出结果如下 Python常见对象的可迭代性
abc :<class 'str'>
is iterable >> True 123456 :<class 'int'>
is iterable >> False [1,2,4,5,6] :<class 'list'>
is iterable >> True {1,2,4,5,8,5,5,5,5} :<class 'set'>
is iterable >> True (1,2,4,5,6,8) :<class 'tuple'>
is iterable >> True {'a':1,'b':2} :<class 'dict'>
is iterable >> True Obj() :<class '__main__.Obj'>
is iterable >> False Fab(2) :<class '__main__.Fab'>
is iterable >> True
迭代对象的next方法
'''
Created on 2018年1月5日 @author: cq
''' def main():
str1 = 'hello world!'
list1 = [1,2,3,4,5,6]
dicts1 = {'name' : "bob", 'age' : "", 'city' : "Paris", 'gender' : "male" } print("迭代输出可迭代对象'字符串'的元素")
list_iter = iter(str1)
for i in range(len(str1)):
print(list_iter.__next__())
print("----------------------") print("迭代输出可迭代对象[列表]的元素")
list_iter = iter(list1)
for i in range(len(list1)):
print(list_iter.__next__())
print("----------------------") print("迭代输出可迭代对象{字典}的元素")
list_iter = iter(dicts1.keys())
for i in range(len(dicts1)):
print(list_iter.__next__())
print("----------------------") print("迭代输出可迭代对象{字典}的元素")
list_iter = iter(dicts1.values())
for i in range(len(dicts1)):
print(list_iter.__next__())
print("----------------------") print("迭代输出可迭代对象{字典}的元素")
list_iter = iter(dicts1.items())
try:
while True:
print(list_iter.__next__())
except StopIteration:
pass if __name__ == '__main__':
main()
# 输出 迭代输出可迭代对象'字符串'的元素
h
e
l
l
o w
o
r
l
d
!
----------------------
迭代输出可迭代对象[列表]的元素
1
2
3
4
5
6
----------------------
迭代输出可迭代对象{字典}的元素
name
age
city
gender
----------------------
迭代输出可迭代对象{字典}的元素
bob
18
Paris
male
----------------------
迭代输出可迭代对象{字典}的元素
('name', 'bob')
('age', '')
('city', 'Paris')
('gender', 'male')
Result
可迭代类的使用
'''
Created on 2018年1月5日 @author: cq
'''
import time class EvenNumber(object):
def __init__(self, index=0):
self.index = index + 1 # 声明可迭代类,并返回当前对象做为可迭代对象
# 该方法不会在类实例化的时候调用,当该类做为迭代对象使用时,有且在当前类调用一次
def __iter__(self):
print("---------",self.index)
return self # 与迭代对象一样,调用next方法获取对象
def __next__(self):
self.index -= 1
if self.index < 0:
raise StopIteration
elif divmod(self.index, 2) == (self.index/2,0):
return self.index def main():
for i in EvenNumber(12):
if i is not None:
print(i) if __name__ == '__main__':
main()
# 输出结果
# 输出小于该数的偶数 --------- 13
12
10
8
6
4
2
Result
生成器generator
定义:一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator),如果函数中包含yield语法,那这个函数就会变成生成器
'''
Created on 2018年1月5日 @author: cq
''' import time # 此函数包含yield语法,是生成器 ,只能等待__next__()方法唤醒返回迭代对象
def salaryMan(name):
""" """
print("%s: ~~~~~太早了关闹钟继续睡\n" % name)
while True:
plan = yield
print("%s: 今天的计划是 %s" % (name, plan))
if plan == "爬山" or plan == "打球":
print("%s: 睡个X儿,%s去" % (name, plan))
else:
print("%s: 不想去太困了,再睡伙\n" % name) def alarmClock():
iterable2 = sleeper1.__next__()
iterable3 = sleeper2.__next__()
print("刚响就被关掉了,2S后在响吧...\n")
time.sleep(2)
plan_list = ["打球", "爬山", "看电影", "逛街"]
while len(plan_list):
print("闹钟又响了~~~")
sleeper1.send(plan_list.pop())
sleeper2.send(plan_list.pop())
time.sleep(1) def main():
global sleeper1,sleeper2
sleeper1 = salaryMan("老王")
sleeper2 = salaryMan("老李")
print("闹钟还有1S响...\n")
time.sleep(2)
alarmClock() if __name__ == '__main__':
main()
# 输出结果 闹钟还有1S响... 老王: ~~~~~太早了关闹钟继续睡 老李: ~~~~~太早了关闹钟继续睡 刚响就被关掉了,2S后在响吧... 闹钟又响了~~~
老王: 今天的计划是 逛街
老王: 不想去太困了,再睡伙 老李: 今天的计划是 看电影
老李: 不想去太困了,再睡伙 闹钟又响了~~~
老王: 今天的计划是 爬山
老王: 睡个X儿,爬山去
老李: 今天的计划是 打球
老李: 睡个X儿,打球去
Result
扩展:基于yield生成器对象,实现异步回调
from queue import Queue
from functools import wraps def apply_async(func, args, *, callback):
# Compute the result
result = func(*args) # Invoke the callback with the result
callback(result) class Async:
def __init__(self, func, args):
self.func = func
self.args = args def inlined_async(func):
@wraps(func)
def wrapper(*args):
f = func(*args)
result_queue = Queue()
result_queue.put(None)
while True:
result = result_queue.get()
try:
## 注意,这里不仅发送消息给生成器,并且等待生成器返回值
a = f.send(result)
apply_async(a.func, a.args, callback=result_queue.put)
except StopIteration:
break
return wrapper def add(x, y):
return x + y @inlined_async
def test():
for n in [x for x in range(10) if x % 2 == 0]:
r = yield Async(add, (n, n))
print(r) if __name__ == '__main__':
test()
0
4
8
12
16
Result
装饰器decorator
函数调用+函数嵌套+高阶函数
函数调用:执行其他地方的函数体
函数嵌套:就是指在某些情况下,需要将某函数作为另一函数的参数使用
高阶函数:接受一个或多个函数作为参数,即形式参数中接收函数
装饰器满足开闭原则
对于扩展是开放的,对于修改是关闭的。
功能:
当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为而不用修改源代码,避免影响原来应用的运行
'''
Created on 2018年1月5日 @author: cq
''' import time def time_cost(func):
def wrapper(*args,**kwargs):
sTime = time.time()
func(*args,**kwargs)
print("Time cost:%s"%(time.time()-sTime))
return wrapper # 在不改变算法函数的同,添加计算时间开销的功能
@time_cost
def algorithm():
print("算法开始执行...")
time.sleep(2) if __name__ == '__main__':
algorithm()
# 输出结果 算法开始执行...
Time cost:2.0004446506500244
Result
参考博客:http://www.cnblogs.com/alex3714/articles/5143440.html
python中的迭代器&&生成器&&装饰器的更多相关文章
- python中的迭代器 生成器 装饰器
什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,_ ...
- Python基础-迭代器&生成器&装饰器
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 我现在有个需求,看 ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- Day4 - Python基础4 迭代器、装饰器、软件开发规范
Python之路,Day4 - Python基础4 (new版) 本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 ...
- Python基础4 迭代器、装饰器、软件开发规范
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- 迭代器/生成器/装饰器 /Json & pickle 数据序列化
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化
生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...
- 4.python迭代器生成器装饰器
容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...
- Python学习——迭代器&生成器&装饰器
一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...
随机推荐
- BZOJ 1935: [Shoi2007]Tree 园丁的烦恼 [树状数组 离线 离散化]
传送门 刚才我还在郁闷网上怎么没人用$CDQ$分治做 突然发现根本没有时间序.... #include<iostream> #include<cstdio> #include& ...
- 数据分析之pandas教程-----概念篇
目录 1 pandas基本概念 1.1 pandas数据结构剖析 1.1.1 Series 1.1.2 DataFrame 1.1.3 索引 1.1.4 pandas基本操作 1.1.4. ...
- 为Android添加JNI支持
起因 今天在进行Android原生开发时,需要通过JNI调用C++代码实现一些处理.以前没有做过类似的东西,在网上找了很久才解决问题,特记录下来以便以后翻阅. Eclipse无cygwin编译so的方 ...
- 腾讯IVWEB前端工程化工具feflow思考与实践
本篇文章主要介绍腾讯IVWEB团队从0到1在工程化的思考和实践.feflow的全称是Front-end flow(前端工作流),致力于提升研发效率和规范的工程化解决方案.愿景是通过feflow,可以使 ...
- console那些你不曾知道的玩法
一.console最常见的四种方法: FireFox(58) Chrome(51) 二.打印对象: 平时想输出对象属性时,可以直接打印对象,对Object使用toString方法会得到 [Object ...
- Hexo博客框架
https://hexo.io/docs/#What-is-Hexo hexo博客应用1 hexo博客应用2 Spark Streaming 消费kafka到HDFS 搭建篇-使用Github-hex ...
- 使用supervisor 进行进程管理时调整最大文件打开数
[supervisord]logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.loglogfile_maxbytes=50MB ; 日志文 ...
- iOS 应用开发,用户密码存储技术--KeyChain
文/清雪飘香(简书作者)原文链接:http://www.jianshu.com/p/c41525172aee著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”. 这次的Xcode 事件,让我 ...
- iOS7控制中心会覆盖由下向上的手势
Expect users to swipe up from the bottom of the screen to reveal Control Center. If iOS determines t ...
- [记录]Python2.7使用argparse模块
# -*- coding: utf8 -*- import argparse #ArgumentParser.add_argument(name or flags-[, action][, nargs ...