• Python 从零学起(纯基础) 笔记 之 迭代器、生成器和修饰器


    Python的迭代器、 生成器和修饰器


    1、 迭代器访问集合元素的一种方式,从第一个到最后,只许前进不许后退

    不要求事先准备好整个迭代过程中的所有元素,仅仅在迭代到某个元素时才计算该元素,而在这之前或者之后,元素可以不存在或被销毁。

    特点:

    • 访问者是不需要关心迭代器内部的结构,仅需要通过next()方法不断去取下一个内容
    • 不能随机访问集合中的某个值,只能从头到尾依次访问。
    • 访问到一半时不能往回退
    • 便于循环比较大的数据集合,节省内存
    1 names = iter(['alex','jack','list'])
    2 print(names)
    3 print(names.__next__())
    4 print(names.__next__())
    5 print(names.__next__())

    结果:

    <list_iterator object at 0x005CC410>

    alex

    jack

    list

    2、  生成器

    定义:

      一个函数调用时返回一个迭代器,那这个函数就叫做生成器generator),如果函数中包含yield语法,那这个函数就会发生生成器。

    作用:

      这个yield的主要效果,就是可以使函数中断,并保存中断状态,中断后,代码可以继续往下执行,过一段时间还可以再重新调用这个函数,从上次yield的下一句开始执行。

    例1:

     1 def cash_money(amount):
     2     while amount > 0:
     3         amount -= 100
     4         yield 100
     5         print("取钱啦again")
     6 atm = cash_money(500)
     7 print(type(atm))
     8 print(atm.__next__())
     9 print(atm.__next__())
    10 print("go to 相声")
    11 print(atm.__next__())

    结果:

    <class 'generator'>

    100

    取钱啦again

    100

    go to 相声

    取钱啦again

    100

    一共五百块,先去两百块钱,然后去听相声,之后在回来取100 。 一个循环我可以先跳出去做其他事,然后再回来继续做这件事。

    例2:用yield实现单线程中的异步

     1 import time
     2 def consumer(name):
     3     print("%s 准备吃包子啦!"%name)
     4     while True:
     5         baozi=yield #接收别人发送给他的值
     6         print("包子%s 来了,被%s吃了!" % (baozi,name))
     7 
     8 def producer(name):
     9     c = consumer('A')
    10     c2 = consumer('B')
    11     c.__next__()
    12     c2.__next__()
    13     print("准备做包子啦")
    14     for i in range(10):
    15         time.sleep(1)
    16         print("I finished two baozi!")
    17         c.send('Alex')#通过send给yield发送i
    18         c2.send(i)
    19 
    20 producer("Young")

    可以设置断点,单步运行查看程序运行的过程

    3、  装饰器

    开放封闭原则:已实现的功能代码不允许被修改,但是可以被扩展

    开放:对扩展开放

    封闭:以实现的功能代码块

    没有使用装饰器

     1 def login(func):
     2     print("登录验证.")
     3     return func
     4 
     5 def home(name):
     6     print("Welcome [%s] to home page"%name)
     7 def tv(name):
     8     print("Welcome [%s] to tv page"%name)
     9 def movie(name):
    10     print("Welcome [%s] to movie page"%name)
    11 tv = login(tv)
    12 tv("Young")

    结果:

    登录验证.

    Welcome [Young] to tv page

    使用装饰器:

     1 def login(func):
     2     def inner(arg):
     3         print("登录验证.")
     4         func(arg)
     5     return inner
     6 
     7 def home(name):
     8     print("Welcome [%s] to home page"%name)
     9 
    10 @login  # 程序一执行就相当于执行tv = login(tv)
    11 def tv(name):
    12     print("Welcome [%s] to tv page"%name)
    13 def movie(name):
    14     print("Welcome [%s] to movie page"%name)
    15 #tv = login(tv)#相当于@login
    16 tv("Young")

    返回值

     1 def login(func):
     2     def inner(*args,**kwagrs):
     3         print("登录验证.")
     4         return func(*args,**kwagrs)
     5     return inner
     6 
     7 def home(name):
     8     print("Welcome [%s] to home page"%name)
     9 
    10 @login  # 程序一执行就相当于执行tv = login(tv)
    11 def tv(name,passwd=123):
    12     print("Welcome [%s] to tv page"%name)
    13     return 4
    14 @login
    15 def movie(name):
    16     print("Welcome [%s] to movie page"%name)
    17 #tv = login(tv)#相当于@login
    18 ret = tv("Young",passwd=123)
    19 print(ret)
    20 movie("Young")

    以下部分一是对上述内容中装饰器的解释和补充,另一个视为下面的复杂应用做铺垫。

    1 def w1(main_func):
    2     def outer(request,kargs):
    3         print('before')
    4         main_func(request,kargs)
    5         print('after')
    6     return outer
    7 @w1
    8 def show():
    9     pass

    解析:

    首先开始执行@w1,然后执行def  w1(main_func):

    对于def  w1(main_func): 主要包括两部分内容 def outer(request,kargs):  return outer 两个部分,对于def outer(request,kargs): 只是函数定义,没有调用,所以不会执行函数内容;然后执行return outer 返回outer。然后show函数被重新定义,即w1(show)的返回值outer = show

    以下内容详细看看(作为理解即可,很多时候用不到):

     1 def Filter(before_func,after_func):
     2     def outer(main_func):
     3         def wrapper(request,kargs):
     4             before_func(request,kargs)
     5             main_func(request,kargs)
     6             after_func(request,kargs)
     7         return wrapper
     8     return outer
     9 
    10 @Filter(before,after)
    11 def Index(request,kargs):
    12     print('Index') 
    1.  执行Filter(before,after),注意是Filter而不是@,而Filter()的内容是def outer()return outer(注:这里outer并没有被调用,所以函数的内容并没有执行)
    2.  因为1  的返回值是outer ,所以开始执行@outer@outerindex作为参数,开始执行到def  outer()(但是wrapper函数内容并没有执行),接下来执行return wrapper ,即返回值是wrapper
    3. 此时新的Insex = wrapper   最后执行的Index=新Index
  • 相关阅读:
    一个利用扩展方法的实例:AttachDataExtensions
    正则表达式语法
    正则表达式30分钟入门教程
    js正则验证两位小数 验证数字最简单正则表达式大全
    SQL Server DBA三十问【转】
    Vue(踩坑)vue.esm.js?efeb:628 [Vue warn]: Error in render: "TypeError: Cannot read property 'length' of undefined" found in
    vue(有必要做的项目优化)
    vue_(根据多种条件过滤评论内容)
    vue(ref父组件使用子组件中定义的方法)
    Vuex(实现加减操作,Vue.set解决自定义属性没有双向数据绑定)
  • 原文地址:https://www.cnblogs.com/Bro-Young/p/5815970.html
Copyright © 2020-2023  润新知