Day 13 匿名函数 :内置函数: 闭包

01 今日大纲内容

  • 如何学习:
    • 一定要把预习加上!
    • 分配比例:
      • 文字总结格式(1/3),晚上20点-21点之前 完成总结以及代码练习
      • 20点-21点之后写作业

02 昨日内容回顾作业讲解

  • 生成器:生成器就是迭代器,生成器是自己用python代表构建的
      1. 生成器函数
      2. 生成器表达式
      3. python内部提供的
    • 如何判断函数与生成器函数
      • yield
      • yield (一个yield对一个next,返回值,不终止)与 return(终止函数,返回值)的区别
    • 吃包子
    • yield from 讲一个可迭代对象,变成一个生成器
    • 列表推导式,生成器表达式
      • 循环模式[变量(加工后的变量 for 变量 in iterable)]
      • 筛选模式[变量(加工后的变量 for 变量 in iterable if 条件)]
    • 内置函数(避免重复造*,提升开发效率,68个)

03 今日内容

  1. 匿名函数:一句话函数,比较简单的函数

    1. 此函数不是没有名字,他是有名字的,他的名字就是你给其设置的变量,比如func

    2. lambda 是定义匿名函数的关键字,相当于函数的def

    3. lambda 后面直接加形参,形参加多少都可以,只要用逗号隔开就行

    4. 返回值在冒号之后设置,返回值和正常函数一样,可以使任意数据类型

    5. 匿名函数不管多复杂,只能写一行,且逻辑结束后直接返回数据
      课上练习:

      匿名函数 :一句话函数,比较简单的函数

      def func(a,b):
      return a + b

      构建匿名函数

      func1 = lambda a,b:a+b
      print(func1(1,2))

    • 接收一个可切片的数据,返回索引为0与2的对应元素(元组形式)
      func2 = lambda a:(a[0],a[2])
      print(func2([22,33,44,55,66]))
    • 写匿名函数,接收两个int参数,将较大的数据返回
      func3 = lambda a,b: a if a > b else b
      print(func3(1,200))
  2. 内置函数
    # python提供了68个内置函数
    # 今天讲的这部分大部分了解即可
    # eval 剥去字符串的运算外衣,运行里面的代码,有返回值**
    s1 = '1 + 3'
    print(s1)
    print(eval(s1))
    s = "{'name':'alex'}"
    print(s,type(s))
    # print(dict(s)) ##错误
    print(eval(s),type(eval(s)))
    # 网络传输的str input 输入的时候,sql注入等等,绝对不能够使用eval,携带病毒的字符串,eval后直接运行病毒

    # exec 与 eval 几乎是一样,代码流
    msg = '''
    for i in range(10):
        print(i)
    '''
    print(msg)
    exec(msg)
    
    
    # hash 哈希值
    print(hash('ahsfgajhhalga'))
    
    # help 帮助
    s1 = 'laksldka'
    print(help(str))
    print(help(str.upper))
    s1 = 'dasd'
    s1.upper()    #对变量本身不更改
    print(s1)
    
    # # callable 判断一个对象是否可以被调用!!!
    s1 = 'aksdajklf'
    # s1()   # TypeError: 'str' object is not callable
    def fun():
        pass
    fun()   #可执行
    print(callable(fun))
    print(callable(s1))
    
    
    # int # 整形
    print(int(4.6))
    
    # float # 浮点型
    print(type(3.6))
    
    # complex 复数
    print(complex(1,2)) #(1+2j)
    
    # bin:将十进制转换成2进制
    print(bin(100))    # 0b1100100
    
    # oct:将十进制转化成八进制字符串并返回
    print(oct(10))     #0o12
    
    # hex:将十进制转化成十六进制字符串并返回
    print(hex(160))    #0xa0
    print(hex(16))    #0x10
    print(hex(13))    #0xd
    
    # divmod !!取商取余
    print(divmod(10,3)) #(3, 1) 商3余1
    
    # round:保留浮点数的小数位数!!
    print(round(3.14156,2))
    
    # pow:求x**y次幂 (三个参数时,对x**y的结果对z取余)
    print(pow(2,3))     #2的三次方,8
    print(pow(2,3,3))   #8除以3 余2
    
    # bytes 编码
    s1 = '太白'
    b = s1.encode('utf-8')
    print(b)
    b = bytes(s1,encoding='utf-8')
    print(b)
    
    # ord:输入字符找到该字符的编码位置
    # ascii Unicode
    print(ord('a'))
    print(ord('中')) #20013
    
    # chr:输入位置,找出对应的字符
    print(chr(98)) # b
    print(chr(20014))   #Unicode
    
    # repr:返回一个对象的string形式(原形毕露)!!!
    s1 = '存龙'
    print(s1)
    print(repr(s1))
    msg = f'我叫{s1}'
    print(msg)
    print(repr(msg))
    
    
    # all 可迭代对象中,全都是True 才是True
    l1 = [1, 2, '太白3', True, [1,2,3], '']
    print(all(l1))  #False
    
    # any :可迭代对象中,有一个是True 就是True
    l1 = [1, 2, '太白3', True, [1,2,3], '']
    print(any(l1))
    
    # print函数
    # print(self, *args, sep=' ', end='\n', file=None)
    print(1,2,3,4)
    print(1,2,3,4,sep='^')
    
    print(1,end=' ')
    print(2)
    
    # list函数
    l1 = [1,2,3,4]
    l2 = list() #[]
    l2 = list('asdhjashf')
    print(l2)   #['a', 's', 'd', 'h', 'j', 'a', 's', 'h', 'f']
    
    dict 字典创建的几种方式
    这季节创建
    # 元组的解构
    dic = dict([(1,'one'),(2,'two'),(3,'three')])   #列表中放元组
    print(dic)
    dic = dict(one=1,two = 2)    #dict中放参数
    print(dic)
    # fromkeys
    # 字典推导式
    
    
    # abs()   #绝对值!!!
    print(abs(-6))
    
    # sum()   #求和!!!
    l1 = [i for i in range(10)]
    s1 = '123456'
    print(sum(l1))  #45
    print(sum(l1,100))  #145
    # print(sum(s1)) #错误 TypeError: unsupported operand type(s) for +: 'int' and 'str'
    
    # reversed 翻转 返回的是一个翻转的迭代器!!!
    l1 = [i for i in range(10)]
    l1.reverse()    #列表的方法,改变了原列表
    print(l1)#[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
    l1 = [i for i in range(10)]
    obj = reversed(l1)  #不对原列表进行操作
    print(l1)   #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(list(l1)) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    # zip 拉链方法
    l1 = [1,2,3,4,5,6]
    tu1 = ('太白','b哥','的干煤化工')
    s1 = 'sadjakjda'obj = zip(l1,tu1,s1)
    print(list(obj))
    
    # 以下方法最最最重要!!!!!!!!!!!
    # min max
    l1 = [33,2,3,54,7,-1,-9]
    print(min(l1))
    # 以绝对值的方法去最小值
    l2 = []
    func = lambda a:abs(a)
    for i in l1:
        l2.append(func(i))
    print(min(l2))
    
    def abss(a):
        '''
        第一次:a = 33 以绝对值 取最小值 33
        第二次:a = 2  以绝对值 取最小值 2
        第三次:a = 3  以绝对值 取最小值 2
        ........
        第六次:a = -1 以绝对值 取最小值 1
        '''
        return abs(a)
    print(min(l1,key = abss)) #abss不加(),使用变量名
    # 凡是可以加key的:他会自动的将可迭代对象中的每个元素按照顺序传入key对应的函数中,
    # 以返回值比较大小
    dic = {'a':3,'b':2,'c':1}
    求出最小的键
    print(min(dic)) #min会按照字典的键去比较大小
    def func(*args):
    '''
        第一次:
        args:'a'  返回值:dic['a']  记录:3
        第二次:
        args:'b'  返回值:dic['b']  记录:2
        第三次:
        args :'c' 返回值:dic['c']  记录:1
    '''
        return dic[args]
    print(min(dic,key=lambda a:dic[a]))
    func = lambda a:dic[a]
    print(min(dic,key=func))
    l2 = [('太白',18), ('alex', 73), ('wusir', 35), ('口天吴', 41)]
    print(min(l2))
    print(min(l2,key=lambda a:l2[1]))
    # max pass
    
    # sorted 加key
    l1 = [22, 33, 1, 2, 8, 7,6,5]
    l2 = sorted(l1)
    print(l1)
    print(l2)
    l2 = [('大壮', 76), ('雪飞', 70), ('纳钦', 94), ('张珵', 98), ('b哥',96)]
    print(sorted(l2))
    print(sorted(l2,key=lambda a:a[1])) #返回的是一个列表,默认从低到高
    print(sorted(l2,key=lambda a:a[1],reverse=True)) #返回的是一个列表,默认从低到高
    
    # filter  列表推导式的筛选模式
    l1 = [2, 3, 4, 1, 6, 7, 8]
    print([i for i in l1 if i > 3]) #返回的是列表
    ret = filter(lambda a:a>3,l1)   #返回的是迭代器
    print(ret)
    print(list(ret))
    
    # map  列表推导式的循环模式
    l1 = [2, 3, 4, 1, 6, 7, 8]
    print([i**2 for i in l1])   #返回的是列表
    ret = map(lambda a:a**2,l1) #返回的是迭代器
    print(list(ret))
    
    
    # reduce    #累加 第一次取2个值,后续一次取1个值,根据函数来计算
    from functools import reduce
    def func(x,y):
        '''
        第一次:x,y:11,2   x+y
        '''
        return x+y
    l = reduce(func,[11,2,3,4,5])
    print(l)
    
  3. 闭包:整个历史中的某个商品的平均收盘价。什么叫平局收盘价呢?就是从这个商品一出现开始,每天记录当天价格,然后计算他的平均值:平均值要考虑直至目前为止所有的价格。
    比如大众推出了一款新车:小白轿车。
    第一天价格为:100000元,平均收盘价:100000元
    第二天价格为:110000元,平均收盘价:(100000 + 110000)/2 元
    第三天价格为:120000元,平均收盘价:(100000 + 110000 + 120000)/3 元
    1.闭包只存在于嵌套函数中
    2.内层函数对外层函数非全局变量(*变量)的引用或使用,就会形成闭包
    3.被引用的非全局变量也称作*变量,这个*变量会与内层函数产生一个绑定关系
    4.*变量不会再内存中消失
    5.闭包的作用,保证数据的安全.函数外访问不到l1
    # 闭包
    # 封闭的东西:保证数据安全

    # 不断输入参数,求平均值 方案一:
    l1 = [] # l1为全局变量,数据不安全
    li = []
    def make_averager(new_value):
        l1.append(new_value)
        total = sum(l1)
        averager = total/len(l1)
        return averager
    print(make_averager(100000))
    print(make_averager(180000))
    print(make_averager(140000))
    print(make_averager(103000))
    print(make_averager(93000))
    
    
    # 方案二:数据安全,l1不能是全局变量
    # 每次执行的时候,l1列表都会重新赋值成[]
    li = []
    def make_averager(new_value):
        l1 = []
        l1.append(new_value)
        total = sum(l1)
        averager = total/len(l1)
        return averager
    print(make_averager(100000))
    print(make_averager(200000))
    
    
    # 方案三:闭包
    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
    print(avg.__code__.co_freevars)
    print(avg(100000))
    print(avg(140000))
    print(avg(167000))
    print(avg(190000))
    print(avg(173000))
    
    def func():
        return 666
    ret = func()    #函数消失了,但是返回值给了ret
    print(globals())
    
    闭包:多用于面试题:什么是闭包?闭包有什么用?
    1.闭包只存在于嵌套函数中
    2.内层函数对外层函数非全局变量的引用或使用,就会形成闭包 (*变量)
    被引用的费全局变量也称作*变量,这个*变量会与内层函数产生一个绑定关系
    *变量不会再内存中消失
    闭包的作用,保证数据的安全.函数外访问不到l1
    
    # 如何判断一个嵌套函数是不是闭包?
    # 例一:是闭包
    def wrapper():
        a = 1
        def inner():
            print(a)
        return inner
    ret = wrapper()
    # 例二:不是闭包
    a = 2
    def wrapper():
        def inner():
            print(a)
        return inner
    ret = wrapper()
    
    
    # 例三:
    #   也是闭包!
    def wrapper(a,b):
        def inner():
            print(a)
            print(b)
        return inner
    # 传值相当于:
    a = 2
    b = 3
    ret = wrapper(a,b)  #ret得到inner
    # 如何利用代码判断闭包,对内层函数进行判断
    print(ret.__code__.co_freevars)
    
    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
    

04 今日总结

  • 匿名函数
  • 内置函数(三颗星一定记住,两颗星尽量记住)
  • 闭包

05 预习内容

  • 装饰器
上一篇:Python 闭包的相关知识


下一篇:python函数的闭包