生成器

在函数中使用yield关键字就会将一个普通的函数变成一个生成器(generator),普通的函数只能使用return来退出函数,而不执行return之后的代码.而生成器可以使用调用一个next方法来返回生成器中上一次yield时候的状态.并且可以使用send方法给yield重新赋值.这样就可以灵活的进入和跳出函数.因此在程序中生成器可以中断当前函数,去执行其它的代码,在合适的时候跳回函数继续执行

def yield_test():
print('befor the first')
first = yield
print(first)
print('before the second')
second = yield
print(second)
print('before the Third')
Third = yield '也可以有返回值'
print(Third)
print('after the Third') #next方法
g = yield_test()
g.__next__()
g.__next__()
yield_text = g.__next__() #获取yield传出的数据,接受数据next和发送数据yield的位置顺序相同
print(yield_text)
# g.__next__() #send方法
g = yield_test()
g.__next__() #做实验时第一次必须是next,send会报错
g.send('2222') #send发送的数据会被赋值给当前yield之前的代码中生效.
#简单说是赋值给前一个yield以便本次代码执行
g.send('3333')

补充:通过这个例子我们发现

1,send方法被生成器当作了一次__next__,并且send的值会复制给上一个yield,

2,yield和__next_方法是一一对应.当next比函数内yield多时,最后一个next会报一个StopIteration异常.

3,yield后的代码会在下一次next调用时才会执行.

4,yield可以发送数据,也可以接受数据.获取数据时要注意传入和传出不同时机才能获取正确的yield值

所以我们通常把生成器用在可循环的对象

def read_file():
read_size = 10
with open('test.txt','rb') as f:
while True:
text = f.read(read_size)
yield text #通过yield获取当前的text值 g = read_file()
while True:
print(g.__next__())
#生成器这样使用会进入一个死循环

补充:

5, 生成器必须要有明确的退出条件,为了不造成死循环. 所以慎用循环.

def read_file():
read_size = 10
with open('test.txt','rb') as f:
while True:
text = f.read(read_size)
if text: #判断文件是否读取完毕
yield text
else:
return g = read_file()
while True:
print(g.__next__())

迭代器

iterable(可迭代对象)可以直接作用与for循环的对象.可迭代对象分为:一,集合数据类型如:str字符串,list列表,dict字典,tuple元组,set集合等.二,生成器generator和带yield的函数.判断是否为iterable对象可以使用函数isinstance().

在python中list等集合数据类型是非常占用内存的,通过使用iter()可以将一个可迭代对象变成一个迭代器.迭代器中不存储具体数据,只是保存了产生这种数据的逻辑对象.在使用时才产生需要的数据,可以大大节省空间.

from collections import Iterator
list = []
for i in range(10):
list.append(i)
print(list,isinstance(list,Iterator)) list_Iterator= iter(list)
print(list_Iterator,isinstance(list_Iterator,Iterator))
for i in list_Iterator:
print(i)

补充:

1, 迭代器中并没有保存真正的数据,只有在我们去通过next方法去迭代器中取数据

2, 迭代器中是按照一定的顺序输出所有数据,不能取指定的数据.

装饰器

装饰器(decorator)是一种函数的高级用法,主要是通过高阶函数和返回函数组合的方式,修饰其它函数.达到被修饰的函数代码不用修改,调用方式也不变的目的.主要作用就是给被修饰的函数添加功能.

  • 原函数不带参数
#假如有这么三个函数,我们需要记录访问时间和函数名,但是又不能修改函数
def home():
print('index page')
def bbs():
print('bbs page')
def news():
print('news page')
home()
bbs()
news()
#加上装饰器后的效果
import time log_list = []
def user_log(func): #将被装饰函数作为参数传入user_log这个装饰器
def wrapper(): #触发执行装饰器的函数
func() #在装饰器内执行原函数
log_time = time.strftime("%Y-%m-%d %H:%M:%S") #装饰器内具体新代码
page_name = func.__name__
log_page = str(log_time+' ->'+page_name)
log_list.append(log_page)
return wrapper #将触发函数返回,一定不要加()执行符号 @user_log
def home():
print('index page') @user_log
def bbs():
print('bbs page') @user_log
def news():
print('news page') home()
bbs()
news()
print(log_list)
  • 带参数的函数
计算函数运行时间的装饰器
import time def time_consum(func):
def wrapper(*args,**kwargs):
start_time = time.time()
func(*args,**kwargs)
print('running',time.time()-start_time)
return wrapper @time_consum
def user_profile(username):
time.sleep(3)
print('welcome %s'%username) user_profile('sylar')
  • 装饰器带参数,
#根据装饰器参数执行不同的功能
import time
log_list = []
def change_type(ch_type='other'):
def decorator(func):
def wrapper(*args,**kwargs):
if ch_type == 'tc':
start_time = time.time()
func(*args,**kwargs)
print('running',time.time()-start_time)
else:
func()
print('other type code')
log_time = time.strftime("%Y-%m-%d %H:%M:%S") # 装饰器内具体新代码
page_name = func.__name__
log_page = str(log_time + ' ->' + page_name)
log_list.append(log_page)
return wrapper
return decorator @change_type()
def home():
print('index page') @change_type('tc')
def user_profile(username):
time.sleep(3)
print('welcome %s'%username) home()
user_profile('sylar')
print(log_list)

递归函数

在函数内部,调用了这个函数自己.就叫做递归函数

#直接使用递归法求解斐波那契数量的第num个数字
def fib(num):
if num<2:
return num
return fib(num-1)+fib(num-2) for i in range(10):
print(fib(i))

补充递归函数必须要有一个明确的结束条件,python中支持最大递归次数1000

python基础(八)生成器,迭代器,装饰器,递归的更多相关文章

  1. 十一. Python基础(11)—补充: 作用域 & 装饰器

    十一. Python基础(11)-补充: 作用域 & 装饰器 1 ● Python的作用域补遗 在C/C++等语言中, if语句等控制结构(control structure)会产生新的作用域 ...

  2. Python之旅Day5 列表生成式 生成器 迭代器 装饰器

    装饰器 器即函数,装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 装饰器涉及的知识点= 高阶函数+函数嵌套+闭包 在遵循下面两个原则的前提下为被装饰者新功能 ...

  3. python基础整理4——面向对象装饰器惰性器及高级模块

    面向对象编程 面向过程:根据业务逻辑从上到下写代码 面向对象:将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程 面向对象编程(Object Oriented Pro ...

  4. Python-Day4 Python基础进阶之生成器/迭代器/装饰器/Json & pickle 数据序列化

    一.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面 ...

  5. Python全栈开发之路 【第五篇】:Python基础之函数进阶(装饰器、生成器&迭代器)

    本节内容 一.名称空间 又名name space,就是存放名字的地方.举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方. 名称空间共3种,分别如下 ...

  6. python基础之带参数装饰器和迭代器

    带参数的装饰器:就是在原装饰器外再包一层函数 def auth(driver='file'): def auth2(func): def wrapper(*args,**kwargs): name=i ...

  7. python基础语法8 叠加装饰器,有参装饰器,wraps补充,迭代器

    叠加装饰器: 叠加装饰器 - 每一个新的功能都应该写一个新的装饰器 - 否则会导致,代码冗余,结构不清晰,可扩展性差 在同一个被装饰对象中,添加多个装饰器,并执行. @装饰1 @装饰2 @装饰3 de ...

  8. python3 速查参考- python基础 7 -> 函数编程之 装饰器、生成器

    装饰器 1.速查笔记 #-- 函数装饰器:是它后边的函数的运行时的声明 由@符号以及后边紧跟的"元函数"(metafunction)组成 @staticmethod def sme ...

  9. python基础16_闭包_装饰器

    不了解是否其他语言也有类似 python 装饰器这样的东西. 最近才发现ECMAScript6也是有生成器函数的,也有 yield  generator 装饰器的基础知识是闭包: # 闭包:嵌套函数, ...

随机推荐

  1. day5、文件乱码怎么解决

    1.1 Linux下,如何将一个乱码的文件进行重命名 方法一: 命令格式:mv $(ls   |egrep "[^a-zA-Z0-9.-]") tandao.tx [root@nb ...

  2. Backbone简单示例

    要的资源: <script type="text/javascript" src="../dep/underscore-1.6.0.min.js"> ...

  3. Python 练习冊,每天一个小程序

    Python 练习冊,每天一个小程序 说明:     Github 原文地址: 点击打开链接 Python 练习冊.每天一个小程序.注:将 Python 换成其它语言,大多数题目也试用 不会出现诸如「 ...

  4. HBase源代码分析之HRegion上MemStore的flsuh流程(一)

    了解HBase架构的用户应该知道,HBase是一种基于LSM模型的分布式数据库.LSM的全称是Log-Structured Merge-Trees.即日志-结构化合并-树. 相比于Oracle普通索引 ...

  5. 一.windows环境下rabbitMQ的的安装和配置

    rabbitMQ是AMQP 0-9-1(高级消息队列协议)的一个实现,使用Erlang语言编写,利用了Erlang的分布式特性.用它来实现分布式消息队列. 1.因为是用Erlang编写的,所以首先要安 ...

  6. 后台程序处理 (一)python asyncio 协程使用

    由于脚本需要在完成事件处理后N秒检查事件处理结果,当执行失败时再执行另一个事件处理. 想要最小化完成这个功能.同时在第一时间就将执行完毕的结果反馈给接口. 因此想到使用协程. 使用之前先翻阅了一下现有 ...

  7. Eclipse 插件安装、升级和卸载的方法

    Eclipse 的插件可以装在内部,也可以装在外部,装在内部的方法很简单:把插件的features和plugins目录copy到eclipse的安装目录即可. eclipse和其插件升级比较频繁,用过 ...

  8. Web前端开发好学吗?谈谈一位学姐的前端工程师之路

    我的第一篇博客....... 我是一名工科女,因高考失利与理想的院校擦肩而过,从而选择了机电专业.毕业后找工作时才发现机电专业的工作并不太适合我.我的父母也支持我转专业求职,但这个过程有时会让我迷茫. ...

  9. 【MySQL】数据库字段类型

    1.数值型 整型 TINYINT SMALLINT MEDIUMINT INT BIGINT 浮点型 FLOAT(m,n) - m表示总位数,n表示小数位数. DOUBLE(m,n) DECIMAL( ...

  10. 迷宫问题 Maze 4X4 (sloved by backtrack)

    Description 给定一个N*N的迷宫中,(0,0)为起始点,(N-1,N-1)为目的地,求可通往目的地的多个解 思路 这道题其实就是简单的DFS,一路探索到底,没路就回溯到交叉口. #incl ...