zoukankan      html  css  js  c++  java
  • 叠加多个装饰器、迭代器、自定义迭代器和xxx生成式

      叠加多个装饰器、迭代器、自定义迭代器和xxx生成式

      一、叠加多个装饰器

        1、加载装饰器就是将原函数名偷梁换柱成了装饰器最内层那个wrapper函数

          在加载完毕后,调用原函数其实就是在调用wrapper函数

        2、当一个被装饰的对象同时叠加多个装饰器时

          装饰器的加载顺序是:自下而上

          装饰器内wrapper函数的执行顺序是:自上而下

        例子:

          import time

          def timmer(func):  #func = wrapper2的内存地址

            def wrapper1(*args,**kwargs):

              print('================>wrapper1运行了')

              start = time.time()

              res = func(*args,**kwargs)  #===================>跳到wrapper2去执行了

              stop = time.time()

              print('run time is %s'%(stop-start))

              return res

            return wrapper1

          

          def auth(engine='file'):

            def xxx(func):  #func = 最原始那个index的内存地址

              def wrapper2(*args,**kwargs):

                print('=====================>wrapper2运行了')

                name = input('username>>>:').strip()

                pwd = input('password>>>:').strip()

                if engine == 'file':

                  print('基于文件的认证')

                  if name == 'egon' and pwd == '123'

                    print('login successful')

                    res = func(*args,**kwargs)

                    return res

                  elif engine == 'mysql':

                    print('基于mysql的认证')

                  elif engine == 'ldap':

                    print('基于ldap的认证')

                  else:

                    print('错误的认证源')

                return wrapper2

              return xxx

          @timmer  #index = timmer(wrapper2的内存地址)  #index = wrapper1的内存地址

          @auth(engine='file')  #@xxx #index = xxx(最原始那个index的内存地址)  #index = wrapper2的内存地址

          def index():

            print('welcome to index page')

            time.sleep(2)

          index()  #wrapper1的内存地址()

      二、迭代器

        1、什么是迭代器

          迭代指的是一个重复的过程,每一次重复都是基于上一次的结果而来的

          li = ['a','b','c','d','e']

          li =('a','b','c','d','e')

          li = 'hello'

          i = 0

          while i < len(li):

            print(li[i])

            i +=1

          迭代器指的是迭代取值的工具,该工具的特点是可以不依赖于索引取值

        2、为何要用迭代器

          为了找出一种通用的&可以不依赖索引的迭代取值方式

        3、如何用迭代器

          可迭代的对象:但凡内置有.__iter__方法的对象都称之为可迭代的对象

          迭代器对象:既内置有__iter__方法,又内置有__next__方法

          关于__iter__方法:

            调用可迭代对象的__iter__会得到一个迭代器对象

            调用迭代器对象的__iter__会得到迭代器本身

        4、总结迭代器的优缺点:

          优点:

          1、提供了一种通用的&可以不依赖索引的迭代取值方式

          2、同一时刻在内存中只有一个值,更加节省内存

          缺点:

          1、取指定值不如索引灵活,并且迭代器是一次性的

          2、无法预知迭代器数据的个数

        可迭代的对象:str,list,tuple,dict,set,文件对象

        迭代器对象:文件对象

        可迭代的对象====》迭代器对象:调用可迭代对象内置的__iter__方法会有一个返回值,该返回值

      就是对应的迭代器对象

        

        dic = {'x':1,'y':2,'z':3}

        iter_dic= dic.__iter__()

        res1 = iter_dic.__next__()

        print(res1)
        res2 = iter_dic.__next__()

        print(res2)

        print(dic.__iter__().__next__())

        print(dic.__iter__().__next__())  #这样定义会重现产生一个可迭代对象,然后会打印x,是错误的~

        迭代器打印文件内容:

          while True:

            try:

              print(iter_dic.__next__())

            except StopIteration:

              break

        for准确地说应该是迭代器循环,for循环的原理如下:

        1、先调用in后面那个值的__iter__方法,得到迭代器对象

        2、执行迭代器.__next__()方法得到一个返回值,然后赋值给一个变量k,运行循环体代码

        3、循环往复,直到迭代器取值完毕抛出异常然后捕捉异常自动结束循环

        dic = {'x':1,'y':2,'z':3}

        iter_dic = dic.__iter__()

        print(iter_dic)

        print(iter_dic.__iter__())

        for k in dic:  #iter_dic=dic.__iter__()

          print(k)

        with open('a.txt',mode='rt',encoding='utf-8') as f:

          for line in f:  #iter_f = f.__iter__()

            print(line)

      三、自定义迭代器

        yield关键字:只能用在函数内

        在函数内但凡包含有yield关键字,再去执行函数,就不会立刻运行函数体代码了

        会得到一个返回值,该返回值称之为生成器对象,生成器本质就是迭代器

        总结yield:

        1、提供一种自定义迭代器的解决方案

        2、yield可用于返回值

          yield VS return

          相同点:都可以用于返回值

          不同点:yield可以暂停函数,yield可以返回多次值,而return只能返回一次值函数就立刻终止

        def func():

          print('=========>第一次')

          yield 1

          print('=========>第二次')

          yield 2

          print('=========>第三次')

          yield 3

          print('=========>第四次')

        g = func()

        #iter(g) = g.__iter__()

        #next(g) = g.__next__()

        res1 = next(g)

        print(res1)

        res2 = next(g)

        print(res2)

        res3 = next(g)

        print(res3)

        res4 = next(g)

        print(res4)

      

      自制一个range函数:

        def my_rage(start,stop,step = 1)

          while start < stop:

            yield start

            start+=step

        res = my_range(1,5,2) 

        next(res)

        next(res) 

        #print(next(res))

        #for item in res:

          #print(item)

        for item in my_range(1,5,2):

          print(item)

      四、xxx生成式

        1、三元生成式

        def max2(x,y):

          if x>y:

            return x

          else:

            return y

        x = 10

        y = 20

        res = '条件成立的值' if x>y else '条件不成立的值'

        print(res)

        2、列表生成式

        l = []

        for i in range(1,11):

          if i > 4:

            res = 'egg%s' %i

            l.append(res)

        print(l)

        l = ['egg%s' %i for i in range(1,11) if i >4]

        print(l)

        names = ['egon','lxx','yyx','cw','alex','wxx']

        l = []

        for name in names:

          if name != 'egon':

            res = '%s_DSB' %name

            l.append(res)

        print(l)

        l = ['%s_DSB' %name for name in names if name !='egon']

        print(l)

        3、生成器表达式

        res = (i**2 for i in range(3))

        print(res)

        print(next(res))

        print(next(res))

        print(next(res))

        print(next(res))  #因为是0-2 所以最多被调用三次 调用第四次的时候会报错

        

        with open('a.txt',mode = 'rt',encoding = 'utf-8') as f:

          data = f.read()

          print(len(data))

        

          res = 0

          for line in f:

            res +=len(line)

          print(res)

          res = sum((len(line) for line in f))

          res = sum(len(line) for line in f)

          print(res)

          res = max([len(line) for line in f])

          res = max((len(line) for line in f))

          res = max(len(line) for line in f)

          print(res)

        4、字典生成式

          items = [('name','egon'),('age',18),('sex','male')]

          dic = {}

          for k,v in items:

            dic[k] = v

          print(dic)

          res = {k:v for k,v in items if k !='sex'}

          print(res)

        5、集合生成式

          res = {i for i in 'hello'}

          print(res)

        

        

  • 相关阅读:
    netbeans 快捷键
    Netbeans Platform的Lookup 边学边记
    Swing中的并发使用SwingWorker线程模式
    转:ExtJS:tabpanel 多个tab同时渲染问题
    NetBeans Platform Login Tutorial
    检测项目
    C#实现通过程序自动抓取远程Web网页信息
    WebClient类
    string字符串的方法
    WebClient的研究笔记认识WebClient
  • 原文地址:https://www.cnblogs.com/xiaocaiyang/p/9720610.html
Copyright © 2011-2022 走看看