zoukankan      html  css  js  c++  java
  • 3、装饰器、迭代器、生成器

    >>>>>>>>>>>>>>>装饰器<<<<<<<<<<<<<<

    1、什么是装饰器

      装饰器就是一个用来为被装饰对象添加新功能的工具
    

    2、为何要用装饰器

      开放封闭原则:一旦软件上线运行之后,应对需改的源代码封闭,对扩展功能开放
      
      原则:
            1、不修改函数内的源代码
            2、不修改函数的调用方式
      装饰器就是在遵顼原则1和2的前提下,为被装饰对象添加新功能
    

    3、如何实现装饰器

    需求:为函数index添加运行时间的功能

    源代码:

    import time
          def index():
                time.sleep(1)
                print('你真帅')
    
          index()
    

    装饰器装饰:

    import time
          def index():
                time.sleep(1)
                print('你真帅')  源代码不变
    

    开始装饰

    
      1    def outter(func):      func =被装饰对象 index函数的内存地址
      2          def wrapper(*args,**kwargs):
      3                start time.time()
      4                res = func(*args,**kwargs)  被装饰对象index函数的内存地址(x,y,z)
      5                stop time.time()
      6                print(('run time is %s')%(stop - start))
      7                return res  返回结果也做到和 index 一样
      8          return wrapper
          
      9    index = outter(index)   outter(被装饰对象index函数的内存地址) -> 返回wrapper函数的内存地址 -> index = wrapper函数的内存地址 
      10   index()    调用方式不变  表象是index本质上是wrapper 
    
    

    >>>>>>>>>>装饰器语法糖<<<<<<<<<<<<

    装饰器语法糖是装饰器的,为了更简单漂亮的使用装饰器

    
    import time
    from functools import wraps   将wrapper的一些其他参数 也都变成index 更完美的装饰index 和 @wraps 一起使用
    
    def outter(func):  # func = 被装饰对象index函数的内存地址
        @wraps(func)
        def wrapper(*args,**kwargs):
            start = time.time()
            res = func(*args,**kwargs)  # 被装饰对象index函数的内存地址(x,y,z)
            stop = time.time()
            print('run time is %s' %(stop - start))
            return res
        return wrapper  # 千万别加括号
    
    @outter  # index = outter(index)  # outter(被装饰对象index函数的内存地址) -> 返回wrapper函数的内存地址---> index = wrapper函数的内存地址
    def index():  # index = 被装饰对象index函数的内存地址
        """这是index函数"""
        time.sleep(1)
        print('from index')
    
    @outter  # home = outter(home)
    def home(name):
        time.sleep(2)
        print("welcome %s to home page" %name)
        return 123
    

    无参装饰器的模板 记住就好

    
    def outter(func):
          def wrapper(*args,**kwargs):
                res = func(*args,**kwargs)
                return res
          return wrapper
    
    

    例 :登录程序

    
    def login(func):
          def wrapper(*args,**kwargs):
                name = input('name>>>>':)
                pwd = input('pwd>>>>>:')
                if name == 'liu' and pwd == '123':
                      res = func(*args,**kwargs)
                      return res
          return wrapper
    @login
    def index():
          print('index')
    index()
    
    

    >>>>>>>>迭代器<<<<<<<<<

    1、什么是迭代器

      迭代器就是指迭代取值的工具
    
      ####什么是迭代?
            迭代就算一个重复取值的过程,但是每一次都在上一次的基础上进行的
    

    比如:

    nums = [111,22,333]
          def get(l):
                i = 0
                while i < len(l)
                print(l[i])
                i += 1
          get(mus)
    

    看到这个有木有想到什么。没错 就是之前的 for 遍历循环,for 循环的本质就是运用迭代器

    2、为何要用迭代器

    ####1、迭代器提供了一种不依赖于索引的、通用的迭代取值方案
    ####2、节省内存
    

    3、如何用迭代器

    ####可迭代的对象
        1、内置有__iter__方法的对象都叫可迭代的对象
    
        调用可迭代对象的__iter__方法,返回的是它的迭代器
    
    ####迭代器对象
        1、内置有__next__方法
        2、内置有__iter__方法
    
        调用迭代器对象的__iter__方法得到的它自己,就跟没调用一样
        调用迭代器对象的__next__方法返回下一个值,不依赖索引
        可以一直调用__next__直到取干净,则抛出异常StopIteration
    

    内置的 类型都是可迭代对象
    字符串str 列表list 字典dict 集合set 元组tuple
    文件本身就是一个迭代器

    在使用while迭代对象的时候

    
    nums_iter = iter(nums)
     while True:
         try:
             res = next(nums_iter)
             print(res)
         except StopIteration: # 取完结束 防止报错崩溃
             break
    

    而 for 的强大在于包含了这些内容

     1、先调用in后那个对象的__iter__方法,拿到迭代器对象
     2、 res = next(迭代器对象),执行一次循环体代码
     3、循环往复步骤2,直到值取干净抛出异常StopIteration,for会捕捉异常结束循环
    for res in nums:
        print(res)
    
    

    <<<<<<<<<<生成器>>>>>>>>>>

    在使用函数的时候 使用return 可以提返回值 但是return 只能返回一次,后面程序会停止运行
    但是有个一函数 yield 可以返回多次,可以暂停函数的运行!!!!

    yield 与 return的异同

    相同点:返回值层面用法一样
    不同点:return只能返回值一次,而yield可以返回多次
    比如
    def func():
    print('xxx')
    yield 111
    print('yyy')
    yield 222
    print('zzz')
    yield 333
    print('mmmm') 最后一行代码mmm 不会被打印出来
    当函数内出现yield关键字,再调用函数并不会触发函数体代码的运行,会返回一个生成器
    g = func()
    print(g) # 生成器就是一种自定义的迭代器

    使用yield 造成一个无限循环的老母鸡 不占用大量空间
    def func():
    res = 1
    while True:
    yield res
    res += 1

    g = func()

    print(next(g))
    print(next(g)) 取一次 只取一个数 就会遇到 yield 暂停

    扩展

    nums =[111,22,33]
    x = iter(nums) x= 迭代器
    for res in x: # x.iter()是返回本身,循环完了
    print(res)
    print('='*50)

    for res in x: # x.iter() 所以本次不会再取到数
    print(res)

    for res in nums: # nums.iter()是生成一个迭代器
    print(res)
    print('='*50)
    for res in nums: # nums.iter()又生成一个新的迭代器
    print(res)

    路漫漫其修远兮,吾将上下而求索!!!

    加油吧!

  • 相关阅读:
    JAVA 解压压缩包中指定文件或实现压缩文件的预览及下载单个或多个指定的文件
    java 解压zip java.lang.IllegalArgumentException: MALFORMED 错误
    Java文件管理系统
    Java实现用汉明距离进行图片相似度检测的
    url 编码(percentcode 百分号编码)
    nodejs进程管理
    nodejs网络编程
    nodejs内存溢出 FATAL ERROR: CALL_AND_RETRY_0 Allocation failed – process out of memory
    connect ECONNREFUSED 127.0.0.1:80错误解决
    nuxtjs如何在单独的js文件中引入store和router
  • 原文地址:https://www.cnblogs.com/liuyang521/p/14211836.html
Copyright © 2011-2022 走看看