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异常,终止迭代.切只能往前,不能倒退. 可迭代对象:遵循迭代写一点对象就是可迭代对象 ...
随机推荐
- laravel中facade serviceprovider的理解
一个serviceprovider就是一个解决某个功能的公用模块,实际上可以直接用在di里注册然后从di中取出,为啥还要搞个facade呢? 有几个方面的原因 1.把实例化移入到serviceprov ...
- [转]MySQL实现分页查询
原文地址:https://blog.csdn.net/starleejay/article/details/78802610 limit 基本实现方式 一般情况下,客户端通过传递 pageNo(页码) ...
- GridView“GridView1”激发了未处理的事件“RowDeleting”
GridView“GridView1”激发了未处理的事件“RowDeleting”. 原因:1.模板列或者buttoncommand里的commandname=“Delete”,“Update”等关键 ...
- 【WPF】屏幕右下角消息提示框
WPF做一个仿QQ的右下角消息提示窗,网上找到几个Demo后,选了一个比较好用的. 博客 http://blog.csdn.net/huangli321456/article/details/5052 ...
- 【WPF】修改数据层ViewModel后,UI界面未同步更新
界面:WPF(MVVM)中将集合类控件ItemsControl的ItemsSource绑定到了ViewModel中的ObservableCollection列表,ItemsControl.ItemTe ...
- Python __str__函数
class Cat: def __init__(self,_name): self.name = _name def __str__(self): return "i am %s" ...
- Qt中如何根据类名来实例化对象
对于Qt 来说,是可以做到运行时,根据对象的类名字(字符串)来获得对象的实例的,这点和一些语言的反射机制是一样的. 但是在Qt中,我们需要所额外的一步,就是注册.只要做到了注册,我们就可以 自由的创建 ...
- Cocos2d-x绘制圆角矩形
/* * @brief 画圆角矩形 * @param origin 矩形开始点 * @param destination 矩形结束点 * @param radius 圆角半径 * @param seg ...
- Java数组排序和插入
如何排序数组并插入元素? 以下示例显示如何使用sort()方法和用户定义的insertElement()方法来完成此任务. package com.yiibai; import java.util.* ...
- JDBC Like子句实例
在本教程将演示如何在JDBC应用程序中,从数据库表中查询数据记录, 在查询选择记录时使用Like子句添加其他条件. 在执行以下示例之前,请确保您已经准备好以下操作: 具有数据库管理员权限,以在给定模式 ...