• day19-python-叠加装饰器分析、yield、三元、生成式、递归


    每日测验

    1、有参装饰器auth
        from functools import wraps
        def deco(x,y,z):
            def outter(func):
                @wraps(func)
                wrapper(*args,**kwargs):
                    res=func(*args,**kwargs)
                    return res
                return wrapper
            return outter
    
    
    2、分析@auth(db_type='file')的执行过程
       @deco(1,2,3) => @outer => 原函数名=outer(被装饰的函数)
    
    3、简述什么是可迭代对象、什么是迭代器对象
        __iter__
        __next__
    4、简述迭代器的优缺点
        def add():
            count=0
            while True:
                count+=1
                yield count
    
        g=add()
        print(next(g))
        print(next(g))
        print(next(g))
        print(next(g))
        print(next(g))
    
        new_g=add()
    
    5、简述for循环工作原理
        for x in 可迭代对象: # 可迭代对象.__iter__()=>迭代器对象-》x=next(迭代器对象)
            print(x)
    6、自定义迭代器实现range功能
        def func():
            yield
    

    今日内容概要

    一、叠加多个装饰器的加载、运行分析(了解***)
        # @deco1 # index=deco1(deco2.wrapper的内存地址)
        # @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址)
        # @deco3 # deco3.wrapper的内存地址=deco3(index)
        # def index():
        #     pass
    
    二、生成器的高级玩法之yield挂起函数:yield的表达式形式(了解***)
        x=yield 返回值
    
    三、三元表达式
    
    四、生成式
        列表生成式
        字典生成式
        生成器表达式
    
    五、函数的递归调用
    

    今日内容详细

    多个装饰器分析推导

    # 一、叠加多个装饰器的加载、运行分析(了解***)
    
    def deco1(func1):  # func1 = wrapper2的内存地址
        def wrapper1(*args, **kwargs):
            print('正在运行===>deco1.wrapper1')
            res1 = func1(*args, **kwargs)
            return res1
        return wrapper1
    
    
    def deco2(func2):  # func2 = wrapper3的内存地址
        def wrapper2(*args, **kwargs):
            print('正在运行===>deco2.wrapper2')
            res2 = func2(*args, **kwargs)
            return res2
        return wrapper2
    
    
    def deco3(x):
        def outter3(func3):  # func3=被装饰对象index函数的内存地址
            def wrapper3(*args, **kwargs):
                print('正在运行===>deco3.outter3.wrapper3')
                res3 = func3(*args, **kwargs)
                return res3
            return wrapper3
        return outter3
    

    加载顺序自下而上(了解)

    @deco1      # index=deco1(wrapper2的内存地址)        ===> index=wrapper1的内存地址
    @deco2      # index=deco2(wrapper3的内存地址)        ===> index=wrapper2的内存地址
    @deco3(111)  # ===>@outter3===> index=outter3(index) ===> index=wrapper3的内存地址
    def index(x, y):
        print('from index %s:%s' % (x, y))
    

    执行顺序自上而下

    wraper1->wrapper2->wrapper3
    index(1, 2)  # wrapper1(1,2)
    

    示意图

    yield高级运用

    x = yield 返回值

    yield可以接受传入的值,调用send

    def dog(name):
        print('道哥%s准备吃东西啦...' % name)
        while True:
            # x拿到的是yield接收到的值
            x = yield  # x = '肉包子'
            print('道哥%s吃了 %s' % (name, x))
    
    
    g = dog('alex')
    g.send(None)  # 等同于next(g),必须先做这一步才能send
    
    g.send(['一根骨头', 'aaa'])
    g.send('肉包子')
    g.send('一同泔水')
    
    g.close()
    g.send('1111') # 关闭之后无法传值
    

    把每个传入的值放入列表中,一起返回

    def dog(name):
        food_list = []
        print('道哥%s准备吃东西啦...' % name)
        while True:
            # x拿到的是yield接收到的值
            x = yield food_list  # x = '肉包子'
            print('道哥%s吃了 %s' % (name, x))
            food_list.append(x)  # ['一根骨头','肉包子']
    
    
    g = dog('alex')
    res = g.send(None)  # next(g)
    print(res)
    
    res = g.send('一根骨头')
    print(res)
    
    res = g.send('肉包子')
    print(res)
    # g.send('一同泔水')
    
    def func():
        print('start.....')
        x = yield 1111  # x='xxxxx'
        print('哈哈哈啊哈')
        print('哈哈哈啊哈')
        print('哈哈哈啊哈')
        print('哈哈哈啊哈')
        yield 22222
    
    
    g = func()
    res = next(g)
    print(res)
    
    res = g.send('xxxxx')
    print(res)
    

    三元表达式

    语法格式: 条件成立时要返回的值 if 条件 else 条件不成立时要返回的值
    
    x = 1
    y = 2
    
    res = x if x > y else y
    print(res)
    
    
    res = 111111 if 'egon' == 'egon' else 2222222222
    print(res)
    
    
    # 应用举例
    def func():
        # if 1 > 3:
        #     x=1
        # else:
        #     x=3
    
        x = 1 if 1 > 3 else 3
    

    生成式

    1、列表生成式

    l = ['alex_dsb', 'lxx_dsb', 'wxx_dsb', "xxq_dsb", 'egon']
    new_l = []
    for name in l:
        if name.endswith('dsb'):
            new_l.append(name)
    
    # 以下简写
    new_l = [name for name in l if name.endswith('dsb')]
    new_l = [name for name in l]
    
    print(new_l)
    

    把所有小写字母全变成大写

    
    new_l = [name.upper() for name in l]
    print(new_l)
    

    把所有的名字去掉后缀_dsb

    
    new_l = [name.replace('_dsb', '') for name in l]
    print(new_l)
    

    2、字典生成式

    keys = ['name', 'age', 'gender']
    dic = {key: None for key in keys}
    print(dic)
    
    items = [('name', 'egon'), ('age', 18), ('gender', 'male')]
    res = {k: v for k, v in items if k != 'gender'}
    print(res)
    

    3、集合生成式

    keys = ['name', 'age', 'gender']
    set1 = {key for key in keys}
    print(set1, type(set1))
    

    4、生成器表达式

    g = (i for i in range(10) if i > 3)
    

    !!!!!!!!!!!注意!!!!!!!!!!!!!!!
    此刻g内部一个值也没有

    print(g, type(g))
    
    print(g)
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    

    统计字数

    with open('笔记.txt', mode='rt', encoding='utf-8') as f:
        方式一:
        res = 0
        for line in f:
            res += len(line)
        print(res)
    
        方式二:
        res = sum([len(line) for line in f])
        print(res)
    
        方式三 :效率最高
        res = sum((len(line) for line in f))
        上述可以简写为如下形式
        res = sum(len(line) for line in f)
        print(res)
    

    函数的递归调用

    一:递归的定义

    函数的递归调用:是函数嵌套调用的一种特殊形式
    具体是指:
    在调用一个函数的过程中又直接或者间接地调用到本身
    
    直接调用本身
    
    
    def f1():
        print('是我是我还是我')
        f1()
    
    f1()
    

    间接接调用本身

    def f1():
        print('===>f1')
        f2()
    
    
    def f2():
        print('===>f2')
        f1()
    
    
    f1()
    

    一段代码的循环运行的方案有两种

    方式一:whilefor循环
    while True:
        print(1111)
        print(2222)
        print(3333)
    
    方式二:递归的本质就是循环:
    def f1():
        print(1111)
        print(2222)
        print(3333)
        f1()
    f1()
    

    二:递归应当有边界

    递归调用不应该无限地调用下去,必须在满足某种条件下结束递归调用

    n = 0
    while n < 10:
        print(n)
        n += 1
    
    
    def f1(n):
        if n == 10:
            return
        print(n)
        n += 1
        f1(n)
    
    
    f1(0)
    

    三:递归的两个阶段

    回溯:一层一层调用下去
    递推:满足某种结束条件,结束递归调用,然后一层一层返回
    
    age(5) = age(4) + 10
    age(4) = age(3) + 10
    age(3) = age(2) + 10
    age(2) = age(1) + 10
    age(1) = 18
    
    
    def age(n):
        if n == 1:
            return 18
        return age(n-1) + 10
    
    
    res = age(5)
    print(res)
    

    四:递归的应用

    l = [1, 2, [3, [4, [5, [6, [7, [8, [9, 10, 11, [12, [13, ]]]]]]]]]]
    
    
    def f1(list1):
        for x in list1:
            if type(x) is list:
                # 如果是列表,应该再循环、再判断,即重新运行本身的代码
                f1(x)
            else:
                print(x)
    f1(l)
    

    作业

    1、文件内容如下,标题为:姓名,性别,年纪,薪资
    egon male 18 3000
    alex male 38 30000
    wupeiqi female 28 20000
    yuanhao female 28 10000
    
    要求:
    从文件中取出每一条记录放入列表中,
    列表的每个元素都是{'name':'egon','sex':'male','age':18,'salary':3000}的形式
    
    2 根据1得到的列表,取出所有人的薪资之和
    3 根据1得到的列表,取出所有的男人的名字
    4 根据1得到的列表,将每个人的信息中的名字映射成首字母大写的形式
    5 根据1得到的列表,过滤掉名字以a开头的人的信息
    6 使用递归打印斐波那契数列(前两个数的和得到第三个数,如:0 1 1 2 3 4 7...)
    7 一个嵌套很多层的列表,如l=[1,2,[3,[4,5,6,[7,8,[9,10,[11,12,13,[14,15]]]]]]],用递归取出所有的值
    
    
    
    # 选做作业:同昨天
    
  • 相关阅读:
    tomcat文件夹没有部署项目和Tomcat中webapps中没有运行项目-上传下载文件和图片
    eclipse和myeclipse设置默认编码格式为UTF-8
    mybatis基础学习1---(配置文件和sql语句)
    idea 快捷键以及包含字符串文件搜索
    idea 设置项目编码
    idea 取消代码下波浪线
    idea打开可选项目
    idea打印gc日志
    idea运行scala有问题
    idea简单使用
  • 原文地址:https://www.cnblogs.com/zdw20191029/p/14553353.html
Copyright © 2020-2023  润新知