1、生成器

生成器的创建方法:

(1)通过列表生成式创建

可以通过将列表生成式的[]改成()

eg:
# 列表生成式
L = [ x*2 for x in range(5)] # L = [0, 2, 4, 6, 8]
# 生成器
G = ( x*2 for x in range(5)) # 此时的G是,<generator object <genexpr> at 0x7f626c132db0>

创建列表生成式和生成器的区别只是最外层的()和[],列表生成式是一个列表,而生成器事宜个可迭代对象。生成器对象可以通过for语句遍历每个元素。

for each in G:
print(each) # 打印结果是 0 2 4 6 8
(2)通过函数来实现

generator非常强大,如果推算的算法比较复杂,用类似的列表生成式的for循环无法实现的时候,可以通过函数来实现。

以著名的斐波拉契数列(Fibonacci), 除第一个和第二个数外,任意一个数都可以由前两个数相加得到:1,1,2,3,5,8,13….

斐波拉契数列用列表生成式不容易写出来,但是用函数把它打印出来很容易:

def fib(times):
n = 0
a, b = 0, 1
while n < times:
yield b # 这里用的yield将b的值返回到生成器中。
a, b = b, a+b
n += 1
return 'done' f = fib(5)
for each in f:
print(each)

上述例子中,在循环过程中不断调用yield,就不会中断函数,但是必须要指定一个结束循环的条件,不然会产生一个无限循环的数列出来。

上述中,用for循环是拿不到return语句的返回值的,如果想拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

g = fib(5)
while True:
try:
x = next(g)
print('value: %d' % x)
except StopIteration as e:
print('生成器返回值:%s' % e.value)
break

这样就可以取到return的返回值了。

(3)生成器的特点

生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。

生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。

生成器的特点:

节约内存
迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的

2、迭代器

迭代是访问集合的一种方式。迭代器是一个可以记住遍历的位置的对象,迭代器对象从第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不能后退。

(1)可迭代对象

可迭代对象可以直接用户for循环的数据类型:

  1. 第一类是集合数据类型:如list,tuple,set,dict,str等等。
  2. 第二类是generator,包括生成器和代yield的生成器函数。
(2)判断是否为可迭代对象

可以使用isinstance()函数来判断一个对象是否是可迭代对象。

from collections import Iterable
isinstance([], Iterable) # 如果是可迭代对象则返回True,反之返回False。

生成器不但可以作用于for循环,而且还可以被next()函数不断调用,知道抛出StopIteration错误,表示无法继续返回下一个值了。

(3)迭代器

可以被next()函数调用并不断返回下一个值得对象称为迭代器(Iterator)

可以使用isinstance()函数来判断一个对象是否是迭代器对象。

from collections import Iterator

isinstance((x for x in range(10)), Iterator)  # 如果是迭代器则返回True,反之False
(4)iter()函数

生成器都是Iterator对象,但是list,dict,str虽然是Iterable,但是不是Iterator。如果想把list,dict,str等可迭代对象变成迭代器,可以使用iter()函数。

isinstance 大专栏  python语法生成器、迭代器、闭包、装饰器总结(iter([]), Iterator)  # 返回值是True,证明iter([])是迭代器。
(5)总结
  1. 凡是可以用for循环的对象,都是可迭代对象类型(iterable)
  2. 凡是可用于next()函数的对象,都是iterator(迭代器)类型。
  3. 集合数据类型,如list,dict,str等是可迭代对象,但不是迭代器,可以通过iter()函数获得一个迭代器对象。

3、闭包

闭包是在函数内部再定义一个函数,并且这个函数用到了外部函数的变量,就将这个函数以及用到的一些变量称之为闭包。简言之,内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

闭包示例:
def line_conf(a, b):
def line(x):
return a*x + b
return line line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5))
print(line2(5))

上例中,函数line与变量a, b构成闭包。在创建闭包的时候,我们通过line_conf的参数a, b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1 和 y = 4x + 5)。我们只要变换参数a, b就可以得到不同的曲线表达函数,由此,闭包也具有提高代码可重复用性的作用。

如果没有闭包,我们需要每次创建直线函数的时候同时说明a, b, x。这样,我们需要更多的参数传递,也减少了代码的可移植性。

闭包总结:
  1. 闭包优化了变量,原来需要类对象完成的工作,闭包也可以完成。
  2. 由于闭包引用的外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存。

4、装饰器

装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代的函数。这个替代的函数可以增添新的功能。

(1)装饰器(decorator)功能
  1. 引入日志
  2. 函数执行时间统计
  3. 执行函数前的预处理
  4. 执行函数后的清理功能
  5. 权限校验等场景
  6. 缓存
(2)装饰器示例
1. 无参数函数
from time import sleep, ctime

def timefun(func):
def wrappedfunc():
print('%s is called at %s'%(func.__name__, ctime())
func()
return wrappedfunc @timefunn
def foo():
print('I am foo') foo()
sleep(2)
foo()
2. 被修饰的函数有参数
from time import ctime, sleep

def timefunc(func):
def wrappedfunc(a, b):
print('%s is called at %s'%(func.__name, ctime())
print(a, b)
func(a, b)
return wrappedfunc @timefunc
def foo(a, b)
print(a+b) foo(3, 5)
sloop(2)
foo(2, 4)
3. 被修饰函数带有不定长参数
from time import ctime, sleep

def timefunc(func):
def wrappedfunc(*args, **kwargs):
print('%s is called at %s'%(func.__name__, ctime())
func(*args, **kwargs)
return wrappedfunc @timefunc
def foo(a, b, c):
print(a+b+c) foo(3,5,2)
sleep(2)
foo(2, 4, 9)
4.装饰器中带有return
from time import ctime, sleep

def timefunc(func):
def wrappedfunc():
print('%s called at %s'%(func.__name__, ctime())
func()
return wrappedfunc @timefunc
def foo():
print('i am foo') @timefunc
def getInfo():
return '----hahahah-----' foo()
sleep(2)
foo() print(getInfo()) #执行结果是
foo called at ....
I am foo
foo called at .....
I am foo
getInfo called at ...
None

有结果可见,带有return的修饰器,如果还是按照上述的写法,则不会返回值。如果把修饰器函数中的func(),改为return func(),则print(getInfo())的执行结果是:
getInfo called at …
—–hahahah—–

这样return能正确返回。

python语法生成器、迭代器、闭包、装饰器总结的更多相关文章

  1. Day4 - Python基础4 迭代器、装饰器、软件开发规范

    Python之路,Day4 - Python基础4 (new版)   本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 ...

  2. Python基础4 迭代器、装饰器、软件开发规范

    本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 孩子,我现在有个需 ...

  3. python基础之迭代器生成装饰器

    基本概念 1.容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中.通常这类数据结构把所有的元 ...

  4. python 函数名 、闭包 装饰器 day13

    1,函数名的使用. 函数名是函数的名字,本质就是变量,特殊的变量.函数名()加括号就是执行此函数. 1,单独打印函数名就是此函数的内存地址. def func1(): print(555) print ...

  5. 【Python入门学习】闭包&装饰器&开放封闭原则

    1. 介绍闭包 闭包:如果在一个内部函数里,对在外部作用域的变量(不是全局作用域)进行引用,那边内部函数被称为闭包(closure) 例如:如果在一个内部函数里:func2()就是内部函数, 对在外部 ...

  6. python基础之迭代器、装饰器、软件开发目录结构规范

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

  7. 简学Python第四章__装饰器、迭代器、列表生成式

    Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群  群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...

  8. Python - 三大器 迭代器,生层器,装饰器

    目录 Python - 三大器 迭代器,生层器,装饰器 一. 容器 二. 可迭代对象(iterable) 三. 迭代器 四. 生成器 五. 装饰器 1. 定义 六. 闭包 Python - 三大器 迭 ...

  9. python函数闭包-装饰器-03

    可调用对象 callable()  # 可调用的(这个东西加括号可以执行特定的功能,类和函数) 可调用对象即  callable(对象)  返回为  True  的对象 x = 1 print(cal ...

随机推荐

  1. springboot访问请求404问题

    新手在刚接触springboot的时候,可能会出现访问请求404的情况,代码没问题,但就是404. 疑问:在十分确定代码没问题的时候,可以看下自己的包是不是出问题了? 原因:SpringBoot 注解 ...

  2. 容斥原理的(二进制思想和质因子分解+模板)hdu4135+ecf81.D

    题:http://acm.hdu.edu.cn/showproblem.php?pid=4135 题意:求[A,B]与N互质的数的个数 #include<iostream> #includ ...

  3. 爬虫笔记(十一)——认识cookie

    什么是cookie? 在爬虫的使用中,如果涉及登录等操作时,经常会使用到cookie.简单的来说,我们访问每一个互联网页面,都是通过HTTP协议进行的,而HTTP协议是一个无状态协议,所谓的无状态协议 ...

  4. python学习笔记(26)-request模块

    python学习笔记 #requests import requests #from class_005.http_resuest import HttpRequest login_url = &qu ...

  5. Rikka with Prefix Sum

    Rikka with Prefix Sum 题目 https://www.nowcoder.com/acm/contest/148/D 题目有三个操作 l到r都添加一个数 取一次前缀和 查询区间和 这 ...

  6. 方格取数(多线程dp,深搜)

    https://www.luogu.org/problem/P1004 题目描述 设有N×N的方格图(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0.如下图所示(见样例): 某 ...

  7. 二十八、rsync同步工具深入

    1.将rsync服务加入到自启动文件rc.local echo "/usr/bin/rsync --daemon" >>/etc/rc.local tail -l rc ...

  8. day14-单继承

    #面向对象的三大特征:继承.多态.封装. #一.单继承: # 1. class Animal: #没有父类,默认继承了顶级父类object类. def __init__(self,name,aggr, ...

  9. 主效应|处理误差 |组间误差|处理效应|随机误差|组内误差|误差|效应分析|方差齐性检验|SSE|SSA|SST|MSE|MSA|F检验|关系系数|完全随机化设计|区组设计|析因分析

    8 什么是只考虑主效应的方差分析? 就是不考虑交互效应的方差分析,即认为因素之间是不相互影响的,就是无重复的方差分析.   什么是处理误差 (treatment error).组间误差(between ...

  10. Apsara Clouder专项技能认证:实现调用API接口

    一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访 ...