• Python之挖掘迭代器、生成器、装饰器三代祖坟


    一、迭代器

    1、迭代器协议 有next方法 一直直到StopIteration终止 (只能往前走不能后退)

    2.可迭代对象 遵行迭代器协议的对象就称之为可迭代对象 转换成可迭代对象:iter方法

    Python中字符串 列表 元组 字典 集合 文件都不是可迭代对象,但是可以转换成可迭代对象iter

    1 l = [1, 2, 3]
    2 iter_l = l.__iter__()
    3 print(iter_l.__next__())
    4 print(iter_l.__next__())
    5 print(iter_l.__next__())
    6 print(iter_l.__next__())
    7 print(next(iter_l))

    二、Python中for循环强大的机制

    for运行机制就是
    1.iter 2.next 3.捕捉StopIteration
    为什么要有for循环
    如果说字符串 列表 元组有序的while也可以实现,但是对于无序的类型呢?只有通过for循环当然有序同样能够进行操作

    三、生成器(可迭代对象)

    1.特征 

     1.自动实现迭代器协议 不再调用iter方法
     2.表现形式 函数式yield 生成器表达式(类似列表推导式)

     1 def test():
     2     yield 1
     3     yield 2
     4     yield 3
     5 
     6 
     7 g = test()
     8 print(g)
     9 print(g.__next__())
    10 print(g.__next__())
    11 print(g.__next__())

    2.三元表达式、列表解析

    1 name = 'eric'
    2 res = 'sb' if name == 'eric' else 'shuai'
    3 print(res)
    4 
    5 l = [i for i in range(10)]
    6 print(l)

     1 l = [i for i in range(10) if i > 5] 2 print(l) 

     生成器 1.比列表解析节省内存牛皮好啊2.函数式的生成器阔以保存函数运行状态

    1 l = (i for i in range(10)) 
    2 print(l.__next__())
    3 print(l.__next__())
    4 print(l.__next__())
    5 print(next(l))
    1 print(sum(i*2 for i in range(101)))

    四、yield关键字

    yield相当于return 控制函数的返回值

    x = yield的另外一个特性 接收send传过来的值,赋值给x

     1 def test():
     2     print('开始啦')
     3     first = yield 1  # return 1 first=None
     4     print('第一次', first)
     5     yield 2
     6     print('第二次')
     7 
     8 
     9 t = test()
    10 res = t.__next__()
    11 print(res)
    12 res = t.send(None)  # send触发生成器下一步运行
    13 print(res)

    五、基于生成器模拟生产者消费者模型

     1 import time
     2 
     3 
     4 def consumer(name):
     5     print('我是%s,我开始准备开始吃包子' % name)
     6     while True:
     7         baozi = yield
     8         time.sleep(1)
     9         print('%s 很开心的把%s吃掉了' % (name, baozi))
    10 
    11 
    12 def producer():
    13     c1 = consumer('eric')
    14     c1.__next__()
    15     for i in range(1, 11):
    16         time.sleep(1)
    17         c1.send('屎馅包子%s' % i)
    18 
    19 
    20 producer()

          杂货

     1 # 函数传递参数时 是引用
     2 # name = 'eric'
     3 #
     4 #
     5 # def show():
     6 #     print(id(name))
     7 #
     8 #
     9 # print(id(name))
    10 # show()
    杂货

    六、装饰器

    本质就是函数,为其它函数添加新的功能

    把握两原则:不修改被修饰函数的源代码 不修改被修饰函数的调用方式

    装饰器=高阶函数+函数嵌套+闭包

      1、高阶函数:传入参数函数名: 为被修饰函数增加功能但是改变了调用方式
      返回值函数名:不修改函数的调用的方式
      把上边两个方式结合起来就实现装饰器了

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 import time
     5 
     6 
     7 def foo():
     8     time.sleep(1)
     9     print('from foo')
    10 
    11 
    12 def timer(func):
    13     """
    14     传入参数函数名
    15     :param func:
    16     :return:
    17     """
    18     start_time = time.time()
    19     func()
    20     stop_time = time.time()
    21     print('函数的运行时间%s' %(stop_time-start_time))
    22 
    23 
    24 timer(foo)   # 违背函数调用方式
    25 
    26 def timer(func):
    27     """
    28     from foo
    29     函数运行的时间1.0009970664978027
    30     from foo  这样确实能够统计出foo运行的时间,调用方式也没改变 但是多执行一次foo函数
    31     :param func:
    32     :return:
    33     """
    34     start_time = time.time()
    35     func()
    36     stop_time = time.time()
    37     print('函数运行的时间%s' %(stop_time-start_time))
    38     return func
    39 
    40 
    41 foo = timer(foo)
    42 foo()
    猛击进军装饰器

      2、函数嵌套

     1 def father(name):
     2     # print('from father %s' %name)
     3 
     4     def son():
     5         # print('我的爸爸是%s' %name)
     6 
     7         def grandson():
     8             print('我的爷爷是%s' %name)
     9         grandson()
    10     son()
    11 
    12 
    13 father('Mr.Wei')

      3、闭包:作用域的一种表现

    类的装饰器实现

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 
     5 def deco(obj):
     6     print(obj)
     7     obj.x = 1
     8     obj.y = 2
     9     return obj
    10 
    11 
    12 @deco  # Foo = deco(Foo)
    13 class Foo:
    14     pass
    15 
    16 
    17 @deco
    18 def test():
    19     print('test')
    20 
    21 
    22 print(Foo.__dict__)
    23 print(test.__dict__)  # 这里也可以说明Python中一切皆对象说明
    24 """
    25 <class '__main__.Foo'>
    26 <function test at 0x00000235EBFD4A60>
    27 {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2}
    28 {'x': 1, 'y': 2}
    29 """

    类的装饰器完善版本

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 
     4 
     5 def Typed(**kwargs):
     6     def deco(obj):
     7         for k, v in kwargs.items():
     8             setattr(obj, k, v)
     9         return obj
    10     return deco
    11 
    12 
    13 @Typed(x=1, y=2)   # Typed(x=1, y=2)---->deco   @deco--->Foo = deco(Foo)
    14 class Foo:
    15     pass
    16 
    17 
    18 @Typed(name='eric')
    19 class Bar:
    20     pass
    21 
    22 
    23 print(Foo.__dict__)
    24 print(Bar.__dict__)

    函数的装饰器实现

     1 def timer(func):  # func=test
     2     def wrapper(*args, **kwargs):
     3         start_time = time.time()
     4         res = func(*args, **kwargs)  # 在运行test()
     5         stop_time = time.time()
     6         print('运行的时间%s' %(stop_time-start_time))
     7         return res
     8     return wrapper
     9 
    10 
    11 @timer   # test = timer(test)
    12 def test():
    13     time.sleep(1)
    14     print('test函数运行完毕')
    15 
    16 
    17 # test = timer(test)  # 返回的是wrapper地址
    18 # test()              # 执行的wrapper函数
    19 print(test())
    20 
    21 # @timer就相当于做了test = timer(test)这件事情
  • 相关阅读:
    Red Hat Enterprise Linux 4 下安装 Oracle 10g [转]
    C# 轻松实现对窗体(Form)换肤[转]
    广州.NET俱乐部第一次活动安排暨动员书
    庆祝广州.net俱乐部成立暨迎接新成员暨讨论社区活动
    有感于广州.NET俱乐部的成立暨全体动员书
    如何在列表模板中增加一个计算列
    BI有感续
    BI有感
    列表属性查看器WebPart
    广州.NET第一次活动内容及演讲安排(本贴持续更新中)
  • 原文地址:https://www.cnblogs.com/Alexephor/p/11197765.html
Copyright © 2020-2023  润新知