函数2

python函数2

一、生成器

  1. python社区,生成器与迭代器看成是一种。生成器的本质就是迭代器。唯一的区别:生成器是我们自己用python代码构建的数据结构。迭代器都是提供的,或者转化得来的。

  2. 获取生成器的三种方式:

    • 生成器函数。(返回的是个生成器)
    • 生成器表达式。
    • python内部提供的一些。
  3. 生成器函数

    1. yield

      1. #只要函数中有yield那么它就是生成器函数而不是函数了。
        # 生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next
        def gen_func():
            for i in range(1,5001):
                yield f'{i}号包子'
        ret = gen_func()
        # [3号包子.]
        for i in range(200):
            print(next(ret))
        for i in range(200):
            print(next(ret))
        
    2. yield from(把作用对象作为迭代器返回)

      1. def func():
            lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
            lst2 = ['馒头', '花卷', '豆包', '大饼']
            yield from lst1
            yield from lst2
        g = func()
        for i in range(8):
            print(next(g))
        
  4. 各种推导式

    1. 列表推导式

      1. 循环模式:[变量(加工后的变量) for 变量 in iterable]

        # 从python1期到python100期写入列表lst
        print([f'python{i}期' for i in range(1,101)])
        print(['python{t}期'.format(t=i) for i in range(1,101)])
        print(['python%s期'%(i) for i in range(1,101)])
        
      2. 筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]

        names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
                 ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
        print([name.upper() for i in names for name in i if name.count('e') == 2])
        
    2. 生成器表达式

      obj = (i for i in range(1,11))
      print(next(obj))
      print(next(obj))
      
    3. 字典推导式(了解)

      lst1 = ['jay', 'jj', 'meet']
      lst2 = ['周杰伦','林俊杰','元宝']
      dic = { lst2[i]: lst1[i] for i in range(len(lst1))}
      
    4. 的集合推导式(了解)

      print({i for i in range(1,11)})
      

二、内置函数

  1. python提供了68个内置函数

    1. eval 剥去字符串的外衣运算里面的代码,有返回值。

      • 字符串里面一定要是可以执行的代码,不能是一个变量没有赋值,字符串里面可以是字符串
      • 网络传输的str input 输入的时候,sql注入等等绝对不能使用eval。
      s1='1+3'
      print(s1)
      print(eval(s1),type(eval(s1)))  
      
      #一个读取文件的eval运用(之前用于淘宝抢单的很长的cookie)
      with open('ww.txt',encoding='utf-8',mode='r') as f:
          tt=f.read()
          t=eval(tt)#脱一次,txt默认都是字符串
          print(t,type(t))
          t1=eval(t)#再脱一次,变成list
          print(t1, type(t1))
      
    2. exec 与eval几乎一样, 代码流。

    3. help(str)帮助文件

    4. callable 判断一个对象是否可被调用

      s1 = 'fdsklfa'
      # s1()
      def func():
          pass
      # func
      # # callable 判断一个对象是否可被调用  ***
      # print(callable(s1))
      # print(callable(func))
      
    5. 复数

      print(complex(1,2))  # (1+2j)
      
    6. 进制转换

      bin:将十进制转换成二进制并返回。  **
      oct:将十进制转化成八进制字符串并返回。  **
      hex:将十进制转化成十六进制字符串并返回。  **
      
    7. divmode/roung/pow

      print(divmod(10,3))
      print(round(3.141592653, 2))  # 3.14
      print(pow(2,3))  **
      print(pow(2,3,3))  #   2**3 % 3
      
    8. byte/ord/chr

      s1 = '太白'
      b = s1.encode('utf-8')
      print(b)
      b = bytes(s1,encoding='utf-8')
      print(b)
      
      对于使用ord ,ascii里有,找ascii位置,没有,去找 Unicode中的位置
      print(ord('a'))  #
      print(ord('中'))  # 20013  Unicode
      # chr:输入位置数字找出其对应的字符 #  **
      # print(chr(97))
      print(chr(20013))  # Unicode
      
    9. repr

      repr:返回一个对象的string形式(原形毕露)
      s1 = '存龙'
      print(repr(s1))#连引号也给你返回的!!!!!!!!
      
    10. all/any

      all:可迭代对象中,全都是True才是True
      any:可迭代对象中,有一个True 就是True
      
    11. sum

      l1 = [i for i in range(10)]
      s1 = '12345'
      print(sum(l1,100))
      print(sum(s1))  # 错误
      
    12. reverse

      # reversed  返回的是一个翻转的迭代器  ***
      # l1 = [i for i in range(10)]
      # # l1.reverse()  # 列表的方法
      
    13. zip

      zip 拉链方法 
      
    14. min/max

      1. min默认会按照字典的键去比较大小。!!!!
      dic = {'a': 3, 'b': 2, 'c': 1}
      print(min(dic))  # min默认会按照字典的键去比较大小。答案a
      print(min(dic,key=lambda args: dic[args]))
      #它会自动的将可迭代对象中的每个元素按照顺序传入key对应的函数中,答案c,还是返回键值
      
      
      
      1. sorted

        • sorted也好,min也罢,当有key时,都会把可迭代对象每个值传进,比较好后,再根据比较好的结果把这传进去的值返回,这也是为什么dict返回键,元祖型列表返回是元祖
        l2 = [('大壮', 76), ('雪飞', 70), ('纳钦', 94), ('张珵', 98), ('b哥',96)]
        print(sorted(l2))
        l2.sort()#也可以哦
        print(sorted(l2,key= lambda x:x[1]))  # 返回的是一个列表,默认从低到高
        print(sorted(l2,key= lambda x:x[1],reverse=True))  # 返回的是一个列表,默认从高到低
        
    15. filter

      1. 制造迭代器
      2. list(迭代器或者迭代对象都可以哦)!!!****************
      3. 把所有true的都返回
      l1 = [2, 3, 4, 1, 6, 7, 8]
      # print([i for i in l1 if i > 3])  # 返回的是列表
      ret = filter(lambda x: x > 3,l1)  # 返回的是迭代器,把所有true的都返回
      print(ret)
      print(list(ret))
      
    16. map

      1. map 列表推导式的循环模式
      l1 = [1, 4, 9, 16, 25]
      print([i**2 for i in range(1,6)])  # 返回的是列表
      ret = map(lambda x: x**2,range(1,6))  # 返回的是迭代器
      print(ret)
      print(list(ret))
      
    17. reduce

      # reduce
      from functools import reduce
      def func(x,y):
          '''
          第一次:x  y  : 11  2     x + y =     记录: 13
          第二次:x = 13   y  = 3    x +  y =   记录: 16
          第三次  x = 16   y = 4 .......
          '''
          return x + y
      
      l = reduce(func,[11,2,3,4])
      print(l)
      
    18. 关于time/datetime的使用

      import time
      import datetime
      t1=time.time()
      t2=time.localtime()
      t3=time.strftime("%Y:%m:%d:%H:%M:%S:%A",t2)
      t4=time.strptime(t3,"%Y:%m:%d:%H:%M:%S:%A")
      t5=datetime.date(year=10,month=2,day=19)
      t6=datetime.time(second=10)
      t7=datetime.datetime(year=10,month=2,day=19,second=19)
      t8=datetime.datetime.now()
      t9=t8.strftime("%Y:%m:%d:%H:%M:%S.%f:%A")
      def ff(*args):
          print(args)
      ff(t1,t2,t3,t4,t5,t6,t7,t8,t9)
      
    19. 关于ramdom模块

      import random
      # 获取[0.0,1.0)范围内的浮点数
      print(random.random())
      
      # # 获取[a,b)范围内的浮点数
      print(random.uniform(3,5))
      
      # # 获取[a,b]范围内的一个整数
      # print(random.randint(3,10))
      
      lst = list(range(10))
      random.shuffle(lst)#shuffle是洗牌的意思
      print(lst)
      
      t = (1,2,3)
      # random.shuffle(t)
      # 通过sample变相实现打乱
      lst = random.sample(t,len(t))
      print(lst)
      
      
      

三、匿名函数

  1. func1 = lambda a,b: a + b
    print(func1(1,2))
    
    lambda a,b: a if a > b else b
    

四、闭包

  1. 闭包1,闭包只能存在嵌套函数中。2, 内层函数对外层函数非全局变量的引用(使用),就会形成闭包。

  2. 闭包是保障变量安全的。当多次引用函数内部的变量时,没有闭包就要设全局变量,就不安全,不设全局变量,局部变量每次引用又会清空。

    1. averager这步真的很关键,如果没有这个,averager的地址和内容就会消失,这一步相当于保留了地址,才有了后面内层函数对外函数的非全局变量的引用,才有闭包
    def make_averager():
        l1 = []
        def averager(new_value):
            l1.append(new_value)
            print(l1)
            total = sum(l1)
            return total/len(l1)
        return averager
    avg = make_averager()  # averager这步真的很关键,如果没有这个,averager的地址和内容就会消失,这一步相当于保留了地址,才有了后面内层函数对外函数的非全局变量的引用,才有闭包
    # print(avg(100000))
    # print(avg(110000))
    # print(avg(120000))
    # print(avg(190000))
    

五、装饰器

  1. 装饰器的原则和作用

    • 开放封闭原则:1.为其增加新的功能 2.在不改变原函数的代码以及调用方式的前提下

    • 下面代码的问题是不满足封闭原则,因为改变了调用方式(为了实现测量时间功能,需要单独调用一遍index,而不是在调用index的同时实现测量时间的功能)

    • import time
      def index():
          '''有很多代码.....'''
          time.sleep(2) # 模拟的网络延迟或者代码效率
          print('欢迎登录博客园首页')
      def dariy():
          '''有很多代码.....'''
          time.sleep(3) # 模拟的网络延迟或者代码效率
          print('欢迎登录日记页面')
      def timmer(f):  # f= index
          start_time = time.time()
          f()  # index()
          end_time = time.time()
          print(f'测试本函数的执行效率{end_time-start_time}')
      timmer(index)#单独调用了哦
      #单独调用了哦
      
  2. 标准装饰器

    index = timmer(index),赋予了等式左边index新的含义,使其指向inner,等式右边的index用到了闭包的概念,再次index()会用到index函数

    我们要记住装饰器很简单,只要记住@timmer:index=timmer(index),timmer(index)用到闭包,index移花接木来完成封闭原则


    import time
    # timmer装饰器
    def timmer(f):
        def inner():
            start_time = time.time()
            f()
            end_time = time.time()
            print(f'测试本函数的执行效率{end_time-start_time}')
        return inner
    
    @timmer # index = timmer(index),赋予了等式左边index新的含义,使其指向inner,等式右边的index用到了闭包的概念,再次index()会用到index函数
    def index():
        '''有很多代码.....'''
        time.sleep(0.6) # 模拟的网络延迟或者代码效率
        print('欢迎登录博客园首页')
        return 666
    ret = index()
    print(ret)
    
  3. 带参数返回的装饰器。

    1. 我们知道index()其实就是inner(),原生index函数的完全由inner函数调用执行,所以原生index的返回值必须在inner里面接收,所以有了r=f()
    import time
    # timmer装饰器
    def timmer(f):
        def inner():
            start_time = time.time()
            # print(f'这是个f():{f()}!!!') # index()
            r = f()
            end_time = time.time()
            print(f'测试本函数的执行效率{end_time-start_time}')
            return r
        return inner
    
    @timmer # index = timmer(index)
    def index():
        '''有很多代码.....'''
        time.sleep(0.6) # 模拟的网络延迟或者代码效率
        print('欢迎登录博客园首页')
        return 666
    # 加上装饰器不应该改变原函数的返回值,所以666 应该返回给我下面的ret,
    # 但是下面的这个ret实际接收的是inner函数的返回值,而666返回给的是装饰器里面的
    # f() 也就是 r,我们现在要解决的问题就是将r给inner的返回值。
    ret = index()  # inner()
    print(ret)
    
  4. 最终版标准的装饰器

    标准版的装饰器;
    def wrapper(f):
        def inner(*args,**kwargs):
            '''添加额外的功能:执行被装饰函数之前的操作'''
            ret = f(*args,**kwargs)
            ''''添加额外的功能:执行被装饰函数之后的操作'''
            return ret
        return inner
    
posted @ 2020-03-21 10:56  意大利面  阅读(91)  评论(0)    收藏  举报