叠加多个装饰器的加载、运行分析

def deco1(func1):
    def warpper1(*args, **kwagrs): #func1 = wrapper2的内存地址
        print('正在运行===》deco1.warpper1')
        res1 = func1(*args, **kwagrs)
        return res1
    return warpper1


def deco2(func2):
    def warpper2(*args, **kwagrs):  #func2 = wrapper3的内存地址
        print('正在运行===》deco2.warpper2')
        res2 = func2(*args, **kwagrs)
        return res2
    return warpper2


def deco3(x):
    def outer3(func3):
        def warpper3(*args, **kwagrs): #fun3=被装饰对象index函数的内存地址
            print('正在运行===》deco3.outer3.warpper3')
            res3 = func3(*args, **kwagrs)
            return res3
        return warpper3
    return outer3


#加载顺序自下而上
@deco1      #index=deco1(warpper2的内存地址)===》index = wrapper1的内存地址
@deco2      #index=deco2(warpper3的内存地址)===> index = wrapper2的内存地址
@deco3(111) #===》@outer3 ====> index=outer(index)====>index=warpper3的内存地址
def index(x, y):
    print('from index %s %s ' % (x, y))

#执行顺序是自上而下的
index(1, 2)


'''
正在运行===》deco1.warpper1
正在运行===》deco2.warpper2
正在运行===》deco3.outer3.warpper3
from index 1 2 
'''

yield 返回值

def func(name):
    print('%s程序开始运行' % name)
    x = yield 1111  # x=jjj
    print('%s程序运行中,x的值等于%s' % (name, x))
    print('哈哈哈')
    print('hahaha')
    yield 222


f = func('不好理解的')
res = f.send(None)  # 也等于next(f)
print(res)
res2 = f.send('jjj')
print(res2)
 
'''
不好理解的程序开始运行
1111
不好理解的程序运行中,x的值等于jjj
哈哈哈
hahaha
222

'''

首先传入参数 ‘不好理解的’ 给func,并返回一个生成器,但是函数不运行,直到出现了 next(f) \ f.send(None)第一次传参必须是None, 函数代码运行到第一个yield处,并返回yield后面的值,函数代码再停止到该位置,直到下一次 next(f) \ f.send(**),首先将send的值传给上一次的yield再赋值给x,然后再返回这一次的yield后的值。

三元表达式
语法格式: 条件成立时返回的值 if 条件 else 条件不成立返回的值

x=2
y=3

print(x if x > y else y)

'''
3
'''

生成式

列表生成式
[expression for item1 in iterable1 if condtion1]

l=['你好啊','你啊','我啊','我去','啊啊啊','呵呵']
new_l=[name for name in l if name.endswith('啊')]
print(new_l)

'''
['你好啊', '你啊', '我啊', '啊啊啊']
'''

将列表中 以"_dsb"为结尾的字符串放入新列表,并且将其转换为大写,最后并除去后缀的’_dsb’

l=['alex_dsb','lxx_dsb','wxx_dsb','xxq_dsb','eogn']
new_l=[name.strip('_dsb').upper() for name in l if name.endswith('_dsb')]
print(new_l)

'''
['ALEX', 'LXX', 'WXX', 'XXQ']
'''

字典生成式:

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)

'''
{'name': None, 'age': None, 'gender': None}
{'name': 'egon', 'age': '18'}
'''

集合生成式

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

'''
{'age', 'gender', 'name'} <class 'set'>
'''

生成器表达式

g=(exp for name in 可迭代对象 if exp2)

计算出一个文本文件的字符数:

with open(r'D:\222.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)
    print(res)
'''
2855
'''

方法一是最直接的方法,每一次循环都将文件的每一行有多少个字符计算出来,将得出的值加到res中,res进行统计,最终打印出res。
方法二是在方法一的基础上进行简化,三行代码简化成一行代码。利用列表生成式,将每一行的字符数,生成为一个列表,再将列表内的元素相加。但是方法二有问题,就是如果文件中的行数过大,列表中的元素也是非常多的。
方法三是利用了生成器表达式,只有在for循环执行next命令时,只有一行的字符数进行统计,避免了方法二的问题

函数递归

直接调用:

def f1():
    print('循环往复')
    f1()


f1()

间接调用:

def f1():
    print('循环往复')
    f2()


def f2():
    print('梅开二度')
    f1()


f1()

递归的两个阶段:

  1. 回溯
一层一层调用下去
  1. 递推
满足某种结束条件,结束递归调用,然后一层一层返回

问5个人年龄,一个人说比第二个人大10岁,第二个人说比第三个人大10岁,第三第四个人也是如此这样说,直到第五个人,才是他是18岁,问第一个人的年龄

def age(n):
    if n == 1:
        return 18
    return age(n-1)+10

print(age(5))


'''
58
'''

利用递归将列表的值打印出来

def f1(l):
    for x in l:
        if type(x) is list:
            f1(x)
        else:
            print(x)

l=[1,2,[3,[4,[5,[6,[7,8,9,10,[11,12,[13,14]]]]]]]]
f1(l)

'''
1 2 3 4 5 6 7 8 9 10 11 12 13 14
'''