python05 - 迭代器,生成器,装饰器
迭代器
迭代器就是访问集合元素的一种方式,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问一遍后结束。
迭代器很大的特点:
- 只能往前迭代,不能够回退,也不能随机访问其中一个元素,只能通过__next__()方法来进行迭代下一个元素。
- 不需要事先准备大量元素,只有该元素被迭代的时候才会生产这个元素。而在该元素被迭代之前之后,元素是不存在或者被销毁的。这样的特性很适合迭代大型数据。
创建一个迭代器并且迭代:
>>> a=iter(['a',1,3,4,'c','x']) #通过iter类来创建一个迭代对象。
>>> a #只会显示这个迭代对象在内存的地址
<list_iterator object at 0x00000200BDC7ACC0>
>>> a.__next__() #通过next方法来迭代下一个对象
'a'
>>> a.__next__()
1
>>> a.__next__()
3
生成器
说到迭代器,那么就不得不说生成器了,那么什么叫生成器??
一个函数内容包含yield,并且调用这个函数,执行后返回一个迭代对象,那么这个函数就称为生成器。
yield的作用:
在一个函数内,如果有yield,那么此时函数会暂时中断,并把中断的状态保存起来(以便等会重新返回到这个状态),同时也把yield后面的值返回,返回以后再次回到函数内接着执行yield后面的语句。
生成器的特性:
- 生成器其实也是一个函数。
- 生成器通过send方法与外界交互。
- 生成器也有next方法。
那么生成器有什么卵用呢?
我们可以通过yield来做个简单的异步执行(通过yield来实现一个简单的生产消费者模型)
import time
def a(name): #定义一个消费者
print("Begin eat")
while 1:
baozi = yield # 把yield的值赋值给baozi
print("%s eat %s"%(name,baozi))
def b(): #定义一个生产者
c=a('ljf')
c.__next__() #调用生成器的next方法
for i in range(1,10):
c.send(i) #调用生成器的send方法与外界交互,通过send方法把i 的值赋值给yield
print("begin shengcan")
time.sleep(2)
b()
装饰器
什么是装饰器呢?从字面上简单的理解就是装饰用的器具,哈哈,其实深入是这样的概念:
所谓装饰器仅仅是一种语法糖, 可作用的对象可以是函数也可以是类, 装饰器本身是一个函数, 其主要工作方式就是将被装饰的类或者函数当作参数传递给装饰器函数, 从而达到一个装饰的效果,我们使用@符号来调用装饰圈。
说到这里,我们得再提下这个原则:
开放封闭原则
虽然这个原则是作用在面向对象的开发,但是同样适用于面向过程的开发,既已实现功能的代码不允许更改,只允许在外部进行扩展。
- 开放:对扩展开发
- 封闭:已经实现功能的代码不允许更改
应用场景:
比如公司新开发好的一个基础运维平台,每个部门都可以去调用这个平台,但是调用的时候不需要验证,那么此时boss提出要求需要添加验证在调用功能之前,此时我们有三个方案:
- 让每个调用者的代码添加验证功能
- 在基础运维平台的每个功能里面添加验证功能的代码
如 :
def f1():
验证 #在原有的代码上插入这段验证的代码
xxx:
def f2():
验证 #同上
xxx:
3 把验证代码封装成一个函数或类,在每个功能里面添加 调用 验证代码
如:
def yanzheng(): #定义一个验证的函数
sssss
def f1():
yanzheng() #在原来的代码调用这个验证的函数
xxx
def f2():
yanzheng() #同上
xxx
自己仔细想想,上面第一个方案是不可行的,因为会牵涉到多个部门更改代码,第二第三个方案是不遵循开放封闭原则,好了,此时装饰器就派上用场了。我们先看代码,再说执行流程
我们先来看代码的演变过程:
最简单的代码
def yanzheng(func):
print("authtication your password!!") #使用最简单的print来替代真正的验证代码段
return func('ljf')
@yanzheng #这里的@yanzheng==yanzheng(test) 把函数作为参数传入yanzheng这个函数里面
def test(name):
print("was be decorator!!")
print('name : %s'%name)
这个段代码有个弊端就是是一运行就会执行yanzheng这个函数的。所以这代码还得改进,改进到等我们调用的时候在执行。
那么就有下面这段代码:
进阶代码
def yanzheng(func):
def warrer(name): #我们在yanzheng这个函数里面再嵌套一层函数并且return 嵌套的函数,这样的话当调用yanzheng的时候,就不 会自动运行test这个函数了。
print("authtication your password!!")
return func(name)
#return func('ljf')
return warrer
@yanzheng
def test(name):
print("was be decorator!!")
print('name : %s'%name)
test('ljf')
那问题来了,如果我函数里面要传入多个参数的时候,那么该怎么处理了呢?
接下来就展现成功修饰的代码,我们加入动态参数:
def yanzheng(func):
def warrer(*args): #这里使用*args来动态的传入参数,还可以调用**kwargs来传入字典
print("authtication your password!!")
return func(*args)
return warrer
@yanzheng
def test(name):
print("was be decorator!!")
print('name : %s'%name)
@yanzheng
def test1(name,age):
print("was be decorator2!!")
print('name %s,age: %s'%(name,age))
test('ljf')
test1('liaojaifa',24) #调用的时候直接传入实参,都是ok没有问题的
打印效果如下:
authtication your password!!
was be decorator!!
name : ljf
authtication your password!!
was be decorator2!!
name liaojaifa,age: 24
python05 - 迭代器,生成器,装饰器的更多相关文章
- Python基础-迭代器&生成器&装饰器
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 我现在有个需求,看 ...
- Python 迭代器&生成器,装饰器,递归,算法基础:二分查找、二维数组转换,正则表达式,作业:计算器开发
本节大纲 迭代器&生成器 装饰器 基本装饰器 多参数装饰器 递归 算法基础:二分查找.二维数组转换 正则表达式 常用模块学习 作业:计算器开发 实现加减乘除及拓号优先级解析 用户输入 1 - ...
- 迭代器/生成器/装饰器 /Json & pickle 数据序列化
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...
- python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化
生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...
- Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- 4.python迭代器生成器装饰器
容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元素存储在内存中 ...
- python中的迭代器&&生成器&&装饰器
迭代器iterator 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外, ...
- day04 迭代器&生成器&装饰器
目录 1.迭代器 2.生成器 3.推导式 4.匿名函数 5.内置函数 6.递归 7.闭包 8.装饰器 一.迭代器 特点: 1. 省内存 2. 只能向前. 不能反复 3. 惰性机制 让不同的数据类型 ...
- Python学习——迭代器&生成器&装饰器
一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...
- Python 全栈开发五 迭代器 生成器 装饰器
一.迭代器 迭代协议:对象必须提供一个next方法,执行该方法后会返回迭代的下一项或者抛出Stopiteration异常,终止迭代.切只能往前,不能倒退. 可迭代对象:遵循迭代写一点对象就是可迭代对象 ...
随机推荐
- Python- requests详解
Requests 是用Python语言编写,基于 urllib,采用 Apache2 Licensed 开源协议的 HTTP 库.它比 urllib 更加方便,可以节约我们大量的工作,完全满足 HTT ...
- 通过USB连接越狱iPhone,SSH进入设备
通过USB连接越狱iPhone,SSH进入设备html, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .Co ...
- 认知计算 Cognitive Computing
认知计算代表一种全新的计算模式,它包含信息分析,自然语言处理和机器学习领域的大量创新技术. Cognnitive computing refers to systems that learn at s ...
- 手动安装 MyEclipse6.5 FindBugs
手动安装步骤: 官方网址:http://findbugs.sourceforge.net/; 下载地址:http://sourceforge.net/projects/findbugs/files/f ...
- Eclipse调试Java的10个技巧【转】
clipse调试Java的10个技巧 先提三点 不要使用System.out.println作为调试工具 启用所有组件的详细的日志记录级别 使用一个日志分析器来阅读日志 1.条件断点 想象一下我们平时 ...
- input 数字输入控制(含小数)
1,可以在keypress里验证输入的字符的合法性. // 数字控件的入力控制 $("input.comma,input.comma1,input.comma2").keypres ...
- sqoop 兼容性问题
--direct 只支持mysql 5.0 + 和postgresql 8.3+(只是import) jdbc的jar包需要放在$SQOOP_HOME/lib目录下 mysql zeroDateTim ...
- SpringBoot2 使用@RestController 无法返回一个地址,前台无法渲染为页面,只能返回json数据
spring boot之访问静态页面 楼主前两天自学spring boot,然后在学习的过程中,出现一个疑问,就是如何去访问静态的html网页,这个问题,楼主上网上搜了下,找到的是在resource目 ...
- 微信小程序——navigator无法跳转
今天在做小程序的时候,发现用navigator无法进行跳转.url 路径也是对的. 后面发现是因为我需要跳转的页面定义在了tabBar里面的.如下图: 如果需要跳转到tabBar里面定义的这些页面,需 ...
- Spring,hibernate,struts的面试笔试题(含答案)
Hibernate工作原理及为什么要用? 原理: 1.读取并解析配置文件 2.读取并解析映射信息,创建SessionFactory 3.打开Sesssion 4.创建事务Transation 5.持久 ...