今日学习目标:
- 学习装饰器的两各类型(多层语法糖,有参装饰器)
- 学习两种算法表达(递归,二分法)
今日学习内容:
内容简要:
- 多层语法糖内部本质
- 有参装饰器
- 递归函数
- 算法之二分法
内容详细:
装饰器(重要)
多层语法糖内部本质
修饰器本质上就是一个函数,只不过它的传入参数同样是一个函数。
举例说明
def deco1(func):
print(1)
def wrapper1():
print(2)
func()
print(3)
print(4)
return wrapper1
def deco2(func):
print(5)
def wrapper2():
print(6)
func()
print(7)
print(8)
return wrapper2
@deco1
@deco2
def index():
print('runing index!')
index()
'''
执行结果
5
8
1
4
2
6
runing index!
7
3
'''
过程说明
- 1.整个程序首先依次加了
deco1()
和deco2()
两个装饰器的原函数index()
实际上相当于deco1(deco2(index))
。 - 2.按照步骤一之后开始执行的是
内层函数deco2(index)
。因此第一个打印值是5
。接下来要注意,在deco2()
这个函数内定义了一个wrapper2()
函数,但是并没有wrapper2()
函数的调用语句所以没有立即执行,而是作为了返回值
。因此wrapper2()
内的语句作为参数传递到了deco1()
内。wrapper2()函数
内还有一行print(8),因此第二个打印值为8
。 - 3.下一步是执行
deco1()函数
内容。与2类似,先打印出1
和4
,返回值为wrapper1()
。由于更外层没有装饰器,因此接下来就将执行wrapper1()
内的内容。第五个打印值为2
。 - 4.接着执行
func()
函数,注意此处func()
表示的是wrapper2()
中的内容,因此跳到wrapper2()
中执行。第六个打印值为6
。类似的,wrapper2()
中的func()
为index()
,因此接着会输出runing index!
。 - 5.最后,回到
wrapper2
和wrapper1
的最后一行,依次输出7
和3
。到这里,整个装饰器的运行过程结束。
有参装饰器
有参装饰器目的仅仅是给装饰器传递额外的参数
装饰器最多就三层嵌套
举例
def auth(db_type):
def deco(func):
def wrapper(*args,**kwargs):
name = input('your name>>:').strip()
pwd = input('your password>>:').strip()
if db_type == 'file':
#从文件中取账号密码进行验证
if name == 'egon' and pwd =='123':
print('基于文件的验证')
res = func(*args,**kwargs)
return res
else:
print('user or password error')
elif db_type == 'mysql':
print('基于mysql的验证')
elif db_type == 'ldap':
print('基于ldap的验证')
else:
print('不支持db_type')
return wrapper
return deco
@auth(db_type = 'file') #@dec0 #index = deco(index) #index=wrapper
def index(x,y):
print('index->>%s:%s' %s (x,y))
@auth(db_type = 'mysql') #账号密码的来源是数据库
def home(name):
print('home--> %s' %name)
@auth(db_type = 'ldap') #账号密码的来源是ldap
def transfer():
print('transfer')
index(1,2)
home('egon')
transfer()
有参装饰器模板
def 有参装饰器(x,y,z):
def outer(func):
def wrapper(*args,**kwargs):
res = func(*args,**kwargs)
return res
return wrapper
return outer
@有参装饰器(1, y =2 , z= 3)
def 被装饰对象():
pass
算法
递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
递归函数特性:
- 必须有一个明确的结束条件;
- 每次进入更深一层递归时,问题规模相比上次递归都应有所减少;
- 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
- 直接或间接的调用自身的函数,递归效率不高;
举例:
计算1到100之间相加之和
def sum_recu(n):
if n > 0:
return n + sum_recu(n - 1)
else:
return 0
print(sum_recu(100))
'''
执行结果
5050
'''
算法之二分法
什么是算法?
算法其实就是解决问题的有效方法
二分法原理
二分法主要是一种数据处理算法,主要的过程就是,拿到数据后将数据按照某种顺序分成两部分,再判断某个数据在那部分,然后将另一个不包含该数据的部分丢掉,将剩下的部分继续按照之前方式处理,直到找到该数据。
注意:二分法使用有前提: 数据集必须有先后顺序(升序 降序)
举例:
猜数字
nums=[-3,4,7,10,13,21,43,77,89]
nums.sort()
find_num=8
def binary_search(find_num,l):
print(l)
if len(l) == 0:
print('找的值不存在')
return
mid_index=len(l) // 2
if find_num > l[mid_index]:
# 接下来的查找应该是在列表的右半部分
l=l[mid_index+1:]
binary_search(find_num,l)
elif find_num < l[mid_index]:
# 接下来的查找应该是在列表的左半部分
l=l[:mid_index]
binary_search(find_num,l)
else:
print('find it')
binary_search(find_num,nums)
'''
#执行结果
[-3, 4, 7, 10, 13, 21, 43, 77, 89]
[-3, 4, 7, 10]
[10]
[]
找的值不存在
'''
今日学习时间:
这里统计计划学习的时间
1、 上午8:30~12:30
2、 下午2:30~5:30
3、 晚上6:30~9:30
今日学习产出:
这里统计学习计划的总量
- 1、 技术笔记 1遍
- 2、CSDN 技术博客 1篇
- 3、每日录音,预习明日内容