昨日回顾
1.双层语法糖(多层语法糖)
def outer(func):
def inner(*args, **kwargs):
'''执行之前添加的功能'''
res=func()
'''执行之后添加的功能'''
return res
return inner
@outer # home=outer(home)
def home():
pass
# index=outer(index)
index()
def outer1():
pass
def outer2():
pass
def outer3():
pass
### 双层语法糖
@outer3 # home=outer3(outer2内部函数的函数名)
@outer2 # outer2内部函数的函数名=outer2(outer1的内部返回值(内层函数的函数名))
@outer1 # outer1的内部返回值(内层函数的函数名)=outer1(home)
def home():
pass
home() # home---->outer3函数内部的函数名
'''多层装饰器的执行顺序:自下而上的依次执行!'''
从下往上,通过外层对函数名赋值,回到被装饰函数触发,运行内部函数执行前功能,再运行被装饰函数,最后运行内部函数执行后功能
def outer1(fuc):
print('outer1')
def inner1(*args,**kwargs):
print('inner1')
res = fuc(*args, **kwargs)
print('inner11')
return inner1
def outer2(fuc):
print('outer2')
def inner2(*args,**kwargs):
print('inner2')
res = fuc(*args, **kwargs)
print('inner22')
return inner2
def outer3(fuc):
print('outer3')
def inner3(*args,**kwargs):
print('inner3')
res = fuc(*args, **kwargs)
print('inner33')
return inner3
@outer1
@outer2
@outer3
def index():
print('index')
index()
# outer3
# outer2
# outer1
# inner1
# inner2
# inner3
# index
# inner33
# inner22
# inner11
2.装饰器修复技术
# 你在写装饰器的时候,修改技术可写可不写
# 固定代码:
from functools import wraps
def outer(func):
@wraps(func)
def inner(*args, **kwargs):
'''执行之前添加的功能'''
res=func()
'''执行之后添加的功能'''
return res
return inner
"""装饰器修复其实就是不容易被我们看出它被装饰了"""
def index():
pass
print(index) # function index at ...
@outer
def index():
pass
print(index) # outer内部的函数名...
help() # 可以查看函数内部的基本信息
3.有参装饰器
在使用糖的情况下,func参数被锁定且只有一个
在无参装饰器的外面再套一层函数,在函数内形成一个局部的全局参数
def outter(source_type, *args1, **kwargs1):
# 'file', 1, 2, 3, 4, 5, 6,
# source_type = 'file'
def login_auth(func): # 参数个数只能有一个
def auth(*args, **kwargs): #
username = input('username:>>>').strip()
password = input('password:>>>').strip()
# 2. 比较用户名和密码
"""
1. 文件中获取用户名和密码
2. 从MySQL中获取用户名和密码
3. 从oracle中获取用户名和密码
4. 从postgresql中获取用户名和密码
"""
# print(a, b, c, d, e, f)
if source_type == 'file':
print('文件中获取用户名和密码')
elif source_type == 'mysql':
print('从MySQL中获取用户名和密码')
elif source_type == 'oracle':
print('从oracle中获取用户名和密码')
elif source_type == 'postgresql':
print('从postgresql中获取用户名和密码')
if username == 'jerry' and password == '123':
# 执行函数
print('登录成功')
func(source_type, *args, **kwargs)
else:
print('用户名或者密码错误')
return auth
return login_auth
@outter('file', 1, 2, 3, 4, 5, 6,) # login_auth(home, file)
# @login_auth # login_auth(home, file)
def home():
pass
home('mysql')
今日内容
1.递归函数
"""
递归:直接或者间接的调用其他函数
"""
def index():
print('from index')
func()
def func():
print('from func')
index()
func()
##### 递归在实际编码中是不允许出现的,一旦出现了无限递归就会直接报错
#### 递归的使用场景
"""
1. 递推
一层一层的往下寻找答案
2. 回溯
通过最后一个结果往回寻找最开始的那个答案
递归是必须有结束条件!!!!
"""
# 使用代码实现以上逻辑
def age(n):
if n == 1:
return 18
# age(5) = age(4) + 2
# age(4) = age(3) + 2
return age(n-1) + 2 # n=2---》age(1)---->age(2)----->age(3)。。。
res=age(5) # 求第5个人的年龄
print(res)
#### 递归实现
def get_list(l):
for i in l:
if type(i) is int:
print(i)
else:
get_list(i)
get_list(l)
2.算法之二分法
算法:就是解决问题的高效办法
算法中的二分法、冒泡排序、选择排序、堆排序、等
# 二分法的使用场景:让你在一个列表中查找某个数字是不是存在
l = [11, 2, 3, 43, 55, 67, 23, 45, 45, 88, 99, 66,]
'''查找66这个数字是否在列表l中'''
1. 实现功能
2. 快速找到
思路:
遍历列表l一个一个去比较,如果比较到了,就是找到了,否则,就是没找到
for i in l:
if i == 66:
print('找到了')
二分法的原理:
1. 列表必须先排序(从小到大,从大到小)
2. 折半查找
代码实现二分法(Python代码):
l = [11, 2, 3, 43, 55, 67, 23, 45, 45, 88, 99, 66,]
# l = ['kevin', 'jerry', 'tank', 'abc']
# 1. 排序
l.sort()
# ['abc', 'jerry', 'kevin', 'tank']
# print(l) # [2, 3, 11, 23, 43, 45, 45, 55, 66, 67, 88, 99]
# 2. 去列表的中间那个值,然后给66比较
target_num = 200
def my_half(l,target_num):
if len(l) == 0:
print('没找到')
return
# 3. 取的就是中间的那个索引
middle_index = len(l) // 2 # 向下取整 5 // 2 == 2 6 // 2 == 3
if target_num > l[middle_index]:
l_right = l[middle_index+1:] #
print(l_right)
my_half(l_right, target_num)
elif target_num < l[middle_index]:
l_left = l[:middle_index]
print(l_left)
my_half(l_left, target_num)
else:
print('找到了')
my_half(l, target_num)
# 请写出你所知道的某个算法
'''冒泡算法'''
3.三元表达式
# 写一个比较两个数大小的函数,返回大的
def my_max(a, b):
if a >b:
return a
else
return b
# 对于只有二选一的情况,我们推荐使用三元表达式
"""
语法结构:
res = 条件成立之后的结果 if 条件 else 条件不成立之后的结果
"""
def my_max(a, b):
return a if a > b else b
res = my_max(1, 2)
# res = '不出去玩' if '下雨' else '出去玩'
# print(res)
# res = '扯淡' if 2 > 10 else 10
# print(res)
"""还支持嵌套"""
## 不推荐写太多的嵌套,一般两层就够了,超过两层了,建议不这样写,面试的时候:成数非常多
res = 2 if 2 > 10 else ( 10 if False else (100 if 10 > 5 else (2 if False else 1)))
print(res)
3.列表生成式
names_list = ['kevin', 'jerry', 'tank', 'oscar']
把列表中得每一个名字后面都拼上后缀_SB
# names_list = ['kevin', 'jerry', 'tank', 'oscar']
# 把列表中得每一个名字后面都拼上后缀_SB
# new_list = [] # 存放拼接之后的人名
# for name in names_list:
# # res = '%s_SB' % name
# res = name + '_SB'
# new_list.append(res)
# print(new_list) # ['kevin_SB', 'jerry_SB', 'tank_SB', 'oscar_SB']
#
# # 列表生成式
# res = [ name + '_SB' for name in names_list]
# print(res)
names_list = ['kevin', 'jerry', 'tank', 'oscar']
# 列表中得每一个名字都拼接上后缀:_SB,除jerry之外
new_list = []
for name in names_list:
if name == 'jerry':
new_list.append(name)
continue
else:
new_list.append(name+'_SB')
print(new_list)
# 列表生成式如何写
# res = [name+'_SB' for name in names_list if name != 'jerry' ]
res = [name+'_SB' if name != 'jerry' else name for name in names_list]
print(res)
4.字典生成式、集合生成式
l1 = ['name', 'age', 'gender']
l2 = ['oscat', 18, 'male']
# d= {'name':oscat, age:18, 'gender':'male'}
# d = {}
# for i in range(len(l1)):
# d[l1[i]] = l2[i]
#
# print(d) # {'name': 'oscat', 'age': 18, 'gender': 'male'}
"""
补充一个方法:enumarate
"""
# for i, j in enumerate(l1):
# # (0, 'name')
# # (1, 'age')
# # (2, 'gender')
# print(i, j)
d = {l1[i]:l2[i] for i, j in enumerate(l1)}
print(d) # 0: 'name', 1: 'age', 2: 'gender'}
"""没有元组生成式"""
s = {i for i, j in enumerate(l1)} # 生成器
print(s)
t = (i for i, j in enumerate(l1))
print(t)