码迷,mamicode.com
首页 > 其他好文 > 详细

函数进阶——闭包,装饰器,生成器,迭代器

时间:2017-12-10 14:26:37      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:创建   循环   迭代   报错   情况   +=   算法   方式   获得   

  • 闭包
    • 函数定义和函数表达式位于另一个函数的函数体内(嵌套函数)。而且,这些内部函数可以访问他们所在的外部函数中声明的所有局部变量、参数。当其中一个这样的内部函数在包含他们的外部函数之外被调用时,就会形成闭包。
  • 装饰器
    • 在不修改原函数的情况下,给原函数增加新的功能,使得程序变得可扩展
    • http://www.cnblogs.com/alex3714/articles/5765046.html(转)
  • 列表生成式
    • 技术分享图片
      1 a = [i+1 for i in range(10)]
      2 print(a)#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      View Code
  • 生成器(generator)
    • 按照一定的算法,在循环的过程中不断推算出后续的元素,可以避免创建完整的list,从而节省大量的空间
    • 创建方式
    • (1)方式一:把列表生成式中的[]换成()通过next()函数获得generator的下一个返回值,直到计算到最后一个元素,没有更多的元素时,抛出StopInteration的错误
    • 技术分享图片
      1 a = (i+1 for i in range(10))
      2 print(a)#<generator object <genexpr> at 0x0000000001E0B8E0>
      3 print(next(a))#1
      4 print(next(a))#2
      5 print(next(a))#3
      View Code
    • (2)generator 是可迭代对象,可用for循环遍历,且不用担心会报错,因此next()基本不用
    • 技术分享图片
      1 a = (i+1 for i in range(10))
      2 print(a)#<generator object <genexpr> at 0x0000000001E0B8E0>
      3 for i in a:
      4     print(i)
      View Code
    • (3)方式二:函数,在函数中添加yield,函数就变成了generator
    • 技术分享图片
       1 #斐波拉契数列
       2 def fib(max):
       3     n,a,b = 0,0,1
       4     while n < max :
       5         yield(b)#把函数的执行过程冻结在这一步,并且把b的值,返回给外面的next()
       6         a,b = b,a+b
       7         n += 1
       8     return "DONE"
       9 a = fib(5)
      10 print(fib(5))#<generator object fib at 0x0000000001DEB8E0>
      View Code
    • (4)yield  VS return
      • return返回并中止函数,return在生成器里,代表生成器的中止,直接报错
      • yield返回数据,并冻结当前的执行过程
      • next唤醒冻结的函数执行过程,继续执行,直到遇到了下一个yield
    • (5)在python2中,range = list,xrange = 生成器,在python3中,range = 生成器,xrange:没有
  • 迭代器
    • 可迭代对象Iterable:可以直接作用域for循环的对象统称为可迭代对象
      • list,tuple,dict,set,str
      • generator,包括生成器和yield的generator function
      • 可以使用isinstance()来判断一个对象是否是Interable对象
      • 技术分享图片
        1 from collections import Iterable
        2 print(isinstance([],Iterable))#True
        3 print(isinstance({},Iterable))#True
        4 print(isinstance("abc",Iterable))#True
        5 print(isinstance((x for x in range(10)),Iterable))#True
        6 print(isinstance(100,Iterable))#False
        View Code
    • 迭代器Iterator:可以被next()函数调用并不断返回下一个值的对象称为迭代器
      • 生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator
      • 可以使用isinstance()判断一个对象是否是Iterator对象:
      • 技术分享图片
        1 from collections import Iterator
        2 print(isinstance([],Iterator))#False
        3 print(isinstance({},Iterator))#False
        4 print(isinstance("abc",Iterator))#False
        5 print(isinstance((x for x in range(10)),Iterator))#True
        6 print(isinstance(100,Iterator))#False
        View Code

        解释:python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIeteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前直到序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的

      • Iter()函数:把list,dict,str等Iterable变成Iterator
      • 技术分享图片
        1 from collections import Iterator
        2 print(isinstance(iter([]),Iterator))#True
        3 print(isinstance(iter("abc"),Iterator))#True
        View Code
      • 小结
        • 凡是可作用于for循环的对象都是Iterable类型;
        • 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列
        • 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象
        • python的for循环本质上就是通过不断调用next()函数实现的。

函数进阶——闭包,装饰器,生成器,迭代器

标签:创建   循环   迭代   报错   情况   +=   算法   方式   获得   

原文地址:http://www.cnblogs.com/GraceZ/p/7956201.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!