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异常,终止迭代.切只能往前,不能倒退. 可迭代对象:遵循迭代写一点对象就是可迭代对象 ...
随机推荐
- Git CMD连接,管理(remote,add,commit,push)github repository
git initmd testcd testgit statusgit add test //git add test/a.txtgit status git remote add origin g ...
- Mybatis generator 自动生成代码(2)
最近准备开始做一个项目,需要开始手动创建sql,于是将Mybatis generator 工具功能强化了下. 首先,这里引入到版本一点的包 <dependency> <groupId ...
- thinkphp前台模版字符串截取
ThinkPHP\Common\extend.php 中管理前台模版的截取{$vons.title|msubstr=0,26} 原始的代码是无法使用截取支持…. 由于涉及到只有汉字检测最为准确 需要加 ...
- 开源一个爬取redmine数据的测试报告系统
背景 软件测试的最后有一道比较繁琐的工作,就是编写测试报告.手写测试报告在数据统计和分析上面要耗费比较大的事件和精力.之前工作室使用mantis管理bug缺陷.公司有内部有个系统,可以直接从manti ...
- matplotlib-plot-style
style 1.绘制x=1 2.不同线宽 enumerate(Widths) 3.线型(实线,虚线,点划线) linestyle set_dashes 4.自动设置线颜色 5.点的显示形式 marke ...
- WPF中Name和x:Name
x:Name用来在XAML中表示一个制定对象的名称:可以通过它来访问XAML对应的资源: Name在.net的很多类中都存在,在WPF中可以和x:Name互换. 结果: 1. 在XAML中只存在x:N ...
- Postgresql查询表的大小
--数据库中单个表的大小(不包含索引) select pg_size_pretty(pg_relation_size('表名')); --查出所有表(包含索引)并排序 SELECT table_sch ...
- 大型机、小型机、x86服务器的区别
原文:http://servers.pconline.com.cn/gc/1202/2679853_1.html 大型机.小型机.x86服务器的区别 首先来讲x86服务器,与平常人们所接触的台式机笔记 ...
- C# 最全的系统帮助类
using System;using System.Collections;using System.Collections.Generic;using System.Configuration;us ...
- Textrank权值提取文本标签提取:
Textrank权值提取文本标签提取: 我已经爬取到了指定博主的新浪微博,然后我想从微博中提取出可以代表该博主兴趣特征的100个关键词,然后由这100个关键词提取出10个标签,代表博主的兴趣.我们此处 ...