day11 - 15(装饰器、生成器、迭代器、内置函数、推导式)

day11:装饰器(装饰器形成、装饰器作用、@语法糖、原则、固定模式)

  1. 装饰器形成:最简单的、有返回值的、有一个参数的、万能参数

  2. 函数起的作用:装饰器用于在已经完成的函数前后增加功能
  3. 语法糖:使代码变得简单
  4. 原则:开放封闭原则,因为已经发布的源码不可以轻易修改,所以使用装饰器在原来的基础上增加功能呢个
  5. 固定模式、万能参数、有返回值
  6.  1 import time
     2 def timmer(func):
     3     def inner(*args,**kwargs):
     4         start = time.time()
     5         time.sleep(1)
     6         ret = func(*args,**kwargs)
     7         end = time.time() - start
     8         return ret,end
     9     return inner
    10 
    11 
    12 @timmer
    13 def func(i):
    14     print(i)
    15     return '***:%s' %i
    16 
    17 res = func('w')
    18 n,t = res
    19 print(n,t)
    固定模式  
  7. 练习题
    1. 编写装饰器、为多个函加上认证功能()
       1 FLAG = False
       2 def timmer(func):
       3     global FALG
       4     def inner (*args,**kwargs):
       5         start = time.time()
       6         if FLAG:
       7             res = func()
       8         else:
       9             res = '登录失败'
      10         return res
      11     return inner
      12 
      13 def Login():
      14     login_user = input('请输入账号:')
      15     login_pass = input('请输入密码:')
      16     with open('user.txt','r',encoding='utf-8') as f:
      17         for i in f:
      18             if 'login_user' in i:
      19                 user_name,user_pass = '|'.join(i)
      20                 break
      21             if login_user == user_name and login_pass == user_pass:
      22                 global FLAG
      23                 FLAG = True
      24             else:
      25                 print('登录失败')
      26                 continue
      27 
      28 
      29 @timmer
      30 def func(a,b):
      31     print(a,b)
      32     return '***:%s;***%s' %(a,b)
      33 
      34 while 1:
      35     command = input('请输入操作序号:]\n1:登录\n2:执行')
      36     if command == '1':
      37         Logon()
      38     elif command == '2':
      39         func()
      40     else:
      41         print('您的输入有误,请重新输入')
      42         continue
      第一题

       

    2. 编写装饰器,为多个函数加上记录调用功能,要求每次调用函数都将被调用的函数名称写入文件

    3. 编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果

    4. 为题目3编写装饰器,实现缓存网页内容的功能:

 

day12:装饰器的进阶(wraps模块、进阶)

  1. wraps模块
    1. 作用:当一个函数被装饰后,使用__name__ 和 __doc__查看函数相关信息时,会查看装饰器的相关信息,wraps的作用就是查看信息时查看的是被点用函数的相关信息
    2. 例子:
       1 from functools import wraps
       2 
       3 
       4 def timmer(func):
       5     @wraps(func)
       6     def inner(*args,**kwargs):
       7         """这个是inner"""
       8         res = func(*args,**kwargs)
       9         return res
      10     return inner
      11 
      12 
      13 @timmer
      14 def func1(a,b):
      15     """这个是func1"""
      16     print(a,b)
      17     return '%s *** %s' % (a,b)
      18 
      19 
      20 print(func1.__name__)
      21 print(func1.__doc__)
      wraps例子

  2. 装饰器进阶
    1. 多个函数怎么同时决定是否使用装饰器
       1 from functools import wraps
       2 FLAGE = True
       3 
       4 def timmer(flage):
       5     def wrapper(func):
       6         @wraps(func)
       7         def inner(*args,**kwargs):
       8             if flage:
       9                 print('装饰前被执行前做的事')
      10                 res = func(*args,**kwargs)
      11                 print('装饰器被执行后做的事')
      12                 return res
      13             else:
      14                 res = func(*args,**kwargs)
      15                 return res
      16         return inner
      17     return wrapper
      18 
      19 
      20 @timmer(FLAGE)
      21 def func1(a,b):
      22     print('执行了,收到了%s 和 %s' %(a,b))
      23     print(func1.__name__)
      24     return 'Ok'
      25 
      26 
      27 @timmer(FLAGE)
      28 def func2(a,b):
      29     print('执行了,收到了%s 和 %s' %(a,b))
      30     print(func2.__name__)
      31     return 'Ok'
      32 
      33 
      34 print(func1('',''))
      35 print(func2('Python','蟒蛇'))
      多个函数同时装饰
    2. 一个函数被多个装饰器调用
       1 def wrapper1(func):
       2     def inner(*args,**kwargs):
       3         print('wrapper1 start')
       4         res = func(*args,**kwargs)
       5         print(res)
       6         print('wrapper1 end')
       7         return res
       8     return inner
       9 
      10 
      11 def wrapper2(func):
      12     def inner(*args,**kwargs):
      13         print('wrapper2 start')
      14         res = func(*args,**kwargs)
      15         print(res)
      16         print('wrapper2 end')
      17         return res
      18     return inner
      19 
      20 
      21 def wrapper3(func):
      22     def inner(*args,**kwargs):
      23         print('wrapper3 start')
      24         res = func(*args,**kwargs)
      25         print(res)
      26         print('wrapper3 end')
      27         return res
      28     return inner
      29 
      30 
      31 @wrapper3
      32 @wrapper2
      33 @wrapper1
      34 
      35 def func():
      36     print(func.__name__)
      37     return 'Func执行完了'
      38 
      39 
      40 
      41 print(func())
      一个函数被多个装饰器调用

       

day13:(迭代器、生成器)

  1. 迭代器
    1. 从容其中一个一个取值,会把所有数据拿到
    2. 节省内存
    3. 迭代器协议和可迭代协议
    4. 可以被for循环的都是可迭代的
    5. 可迭代的内部都有__iter__方法
    6. 只要是迭代器,一定可以迭代
    7. 可迭代的.__iter__()就可以获取一个迭代器
    8. 迭代器中的__next__()方法可以一个一个的获取值
    9. 检验迭代器和可迭代的方法
      1 from collections import Iterable
      2 from collections import Iterator
      3 print(isinstance([],Iterable))
      4 print(isinstance([],Iterator))
      检验方法

       

  2. 生成器
    1. 只要含有yield关键字的函数都是生成器函数
    2. yield不能和return共用且需要写在函数内
    3. 简单的一个生成器
      1 def generator():
      2     print(1)
      3     yield 'a'
      4 
      5 
      6 # 取值
      7 ret = generator()
      8 print(ret.__next__())
      简单生成器

       

day14:(生成器函数进阶、表达式、各种推导式)

  1. 生成器进阶
    1. send:获取下一个值的效果和next基本一致,第一次不能用send
    2. 例子
      1. 获取平均值
         1 def average():
         2     sum = 0
         3     count = 0
         4     avg = 0
         5     while True:
         6         num = yield avg
         7         sum += num    # 10
         8         count += 1    # 1
         9         avg = sum/count
        10 
        11 avg_g = average()
        12 print(avg_g.__next__())
        13 avg1 = avg_g.send(10)
        14 avg1 = avg_g.send(20)
        15 avg1 = avg_g.send(30)
        16 print(avg1)
        获取平均值

         

      2. 预激活生成器,就是使用装饰器,让send可以第一次使用
         1 def init(func):   #装饰器
         2     def inner(*args, **kwargs):
         3         g = func(*args, **kwargs)    #g = average()
         4         g.__next__()
         5         return g
         6     return inner
         7 
         8 @init
         9 def average():
        10     sum = 0
        11     count = 0
        12     avg = 0
        13     while True:
        14         num = yield avg
        15         sum += num    # 10
        16         count += 1    # 1
        17         avg = sum/count
        18 
        19 
        20 avg_g = average()   #===> inner
        21 ret = avg_g.send(10)
        22 print(ret)
        23 ret = avg_g.send(20)
        24 print(ret)
        预激生成器的装饰器

         

      3. 小技巧
         1 def generator():
         2     a = 'abcde'
         3     b = '12345'
         4     for i in a:
         5         yield i
         6     for i in b:
         7         yield i
         8 def generator():
         9     a = 'abcde'
        10     b = '12345'
        11     yield from a
        12     yield from b
        13 
        14 g = generator()
        15 for i in g:
        16     print(i)
        小技巧

         

  2. 生成器表达式
    g = (i for i in range(10))
    print(g)
    for i in g:
        print(i)

     

  3. 各种推导式
     1 # 列表:
     2     ret = [i*i for i in (1,2,3,4) if i%3 == 0]
     3         print(ret)
     4 例子:
     5 找到嵌套列表中名字含有两个‘e’的所有名字
     6 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
     7          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
     8 ret = [name for lst in names for name in lst if name.count('e') ==2]  # 列表
     9 ret = (name for lst in names for name in lst if name.count('e') ==2) # 字典
    10 for i in ret:
    11     print(i)
    12 
    13   
    14 # 字典:
    15     mcase = {'a': 10, 'b': 34}
    16     mcase_frequency = {mcase[k]: k for k in mcase}
    17     print(mcase_frequency)
    18 
    19 #集合推导式,自带结果去重功能
    20 squared = {x**2 for x in [1, -1, 2]}
    21 print(squared)
    各种推导式

     

day15:(面试题、内置函数)

  1. 面试题
    一、
    def demo():
        for i in range(4):
            yield i
    
    g=demo()
    
    g1=(i for i in g)
    g2=(i for i in g1)
    
    print(list(g))
    print(list(g1))
    print(list(g2))
    
    二、
    def add(n,i):
        return n+i
    
    def test():
        for i in range(5):
            yield i
    
    g=test()
    for n in [1,10,5]:
        g=(add(n,i) for i in g)
    
    
    print(list(g))

     

  2. 内置函数:https://www.processon.com/view/link/5c35f503e4b0641c83d55651

 

posted @ 2019-01-09 21:21  董大轩  阅读(202)  评论(0编辑  收藏  举报