(一) 装饰器
1. 引入
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1) # inner 其中参数为f1
res = v1() #执行inner()函数,执行f1()函数,inner函数返回None
print(res)
'''
123
None
'''
def func(arg):
def inner():
return arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1) # inner 其中参数为f1
res = v1() #执行inner()函数,执行f1()函数,f1返回666,inner函数返回666
print(res)
'''
123
666
'''
def func(arg):
def inner():
return arg()
return inner
def index():
print('123')
return '666'
# 示例一
v1 = index() # 执行index函数,打印123,返回666
# 示例二
v2 = func(index) # 开辟内存空间,v2 =inner (含index)
index = 666
v3 = v2() #执行inner函数,执行index函数,返回666
# 示例三
v4 = func(index)
index = v4
index()
2. 装饰器的定义
在不改变原函数的内部代码的前提下,可以在函数执行前后做一些操作
def func(arg):
def inner():
print('before')
v = arg()
print('after')
return v
return inner
#第一步:执行func()并将向岸边的函数作为参数进行传递,相当于func(index)
#第二步:将func的返回值重新赋值给下边的函数鸣,index = func(index)
@func
def index():
print('123')
return "666"
print(index)
3. 装饰器的应用
应用场景:在给函数扩展功能时应用
应用1
import time
def func1():
time.sleep(1)
print('func1')
def func2():
time.sleep(2)
print('func2')
def func3():
time.sleep(3)
print('func3')
start1_time = time.time()
func1()
end1_time =time.time()
print(end1_time-start1_time)
start2_time = time.time()
func2()
end2_time =time.time()
print(end2_time-start2_time)
start3_time = time.time()
func3()
end3_time =time.time()
print(end3_time-start3_time)
'''
func1
1.0003492832183838
func2
2.0002355575561523
func3
3.0006797313690186
'''
def func(index):
def inner():
start_time = time.time()
index()
end_time = time.time()
print(end_time - start_time)
return inner
@func
def func1():
time.sleep(1)
print('func1')
@func
def func2():
time.sleep(2)
print('func2')
@func
def func3():
time.sleep(3)
print('func3')
func1()
func2()
func3()
应用2
def add_user():
#1. 判断用户是否已经登陆
#2.已经登陆可以继续
pass
def del_user():
# 1. 判断用户是否已经登陆
# 2.已经登陆可以继续
pass
def update_user():
# 1. 判断用户是否已经登陆
# 2.已经登陆可以继续
pass
4. 带参数的装饰器
flask框架+django缓存+写装饰器实现被装饰函数要执行N次
def x(num):
def wrapper(func):
def inner(*args,**kwargs):
res = func(*args,**kwargs)
return res
return inner
return wrapper
#1. 执行v1=wrapper(3)
#2. @v1->index(v1) =>res = v1(index)
#3. index = res
@x(3)
#等价于 @wrapper 类似于一个闭包,但是传入的参数,可以进行使用
def index():
pass
注意:在没有调用函数的时候,x(3),wrapper()除inner函数以外就已经被执行了
写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,把每次执行的结果添加到一个列表中,最终返回列表
def calc(num):
def wrapper(func):
def inner(*args,**kwargs):
lst = []
for i in range(num):
res = func()
lst.append(res)
return lst
return inner
return wrapper
@calc(5)
def func():
print('111')
return '666'
v1 = func()
print(v1)
若返回最大值,则为
def calc(num):
def wrapper(func):
def inner(*args,**kwargs):
value = 0
for i in range(num):
res = func()
if res > value:
value = res
return value
return inner
return wrapper
如果有990个函数是做一些操作,10个函数做其他的操作,则可以如下
def calc(counter):
def wrapper(func):
def inner(*args,**kwargs):
lst = []
if counter:
pass
else:
pass
for i in range(counter):
res = func()
lst.append(res)
return lst
return inner
return wrapper
@calc(True)
def func990():
pass
@calc(False)
def func10():
pass
5. 多个装饰器(欠)
x2装饰func , x1 装饰(x2装饰func的结果)
@x1
@x2
def func():
pass
6. 装饰器的总结
- 目的:在不改变原函数的基础上,在函数执行前后自定义功能
- 编写装饰器【记住】
def wrapper(func):
def inner(*args,**kwargs):
res = func(*args,**kwargs)
return res
return inner
@wrapper
def index():
pass
v=index
print(v)
- inner函数参数*args,**kwargs的原因:可以方便多个参数个数不一样的函数进行装饰器的调用
(二) 推导式
1. 列表推导式
目的:方便的生成列表
基本格式
v1 = [ i for i in 可迭代对象]
v1 = [ i for i in 可迭代对象 if 条件] #如果满足条件,则i保留在列表中,否则不保留
val = [i for i in 'alex']
print(val)
v1 = [i+100 for i in range(10)]
print(v1)
v1 = []
for i in range(10):
v1.append(i+100)
print(v1)
v1 = [99 if i >5 else 66 for i in range(10)]
def func():
pass
v4 = [func for i in range(10)] #10个func
v5 = [lambda:100 for i in range(10)] #10个lambda
res = v5[9]()
print(res)
v6 = [lambda:100+i for i in range(10)] #10个lambda
res = v6[9]()
print(res)
v7 = [i for i in range(10) if i >5]
print(v7) #6,7,8,9
#面试题【新浪】
v8 = [lambda x :x*i for i in range(10)]
res = v8[0](2)
print(res)
#面试题
def num():
return [lambda x : i*x for i in range(4)]
# num() [lambda,lambda,lambda,lambda]
print([m(2) for m in num()])
# i = 3
# [lambda 2,lambda 2,lambda 2,lambda 2]
# [6,6,6,6]
2. 集合推导式
除了括号不一样,其他与列表都一样[ ] --> { }
3. 字典推导式
v1 = ['k'+str(i):i for i in range(10)]
print(v1)
其他与列表一样
(三) 迭代器
1. 迭代器的定义
一般自己是不会写迭代器的,要会用。
迭代器帮助对某种对象中的元素进行逐一获取。
- 列表转换成迭代器:iter([11,223,33])
v1 = [11,2,3]
#将列表转换成迭代器
v2 = iter(v1)
print(type(v2))
#将迭代器中的第一个元素取出来
res1 = v2.__next__()
print(res1 )
res2 = v2.__next__()
print(res2 )
res3 = v2.__next__()
print(res3 )
res4 = v2.__next__()
print(res4 )
'''
<class 'list_iterator'>
11
2
3
报错:StopIteration,当超过迭代范围就会终止,并报错
'''
将列表/元组/集合/字符串/字典 【序列】中的每一个元素读出
v1 = [11,2,3]
v2 = iter(v1) #等价于v1.__iter__()
while True:
try:
print(v2.__next__())
except Exception as e:
pass
迭代器的使用步骤
- 列表转换成迭代器,res = iter(v1) 或res = v1__iter__()
- 迭代器想要获取某些值,反复调用val =
v1. __next__()- 直到报错:StopIteration,表示迭代完成
- 如何判断一个对象是否是迭代器:看其内部是否有
__next__()方法- for循环的内部也在调用迭代器
2. 可迭代对象
- 可以被for循环的
- 内部有
__iter()__方法,且返回一个迭代器
(三) 生成器
def func():
print(123)
yield 1
print(11)
yield 2
print(22)
v1 = func()
for item in v1:
print(item)
- 生成器函数,内部含有yield
- 函数内部代码不执行,返回一个生成器对象
- 生成器可以被for循环,一旦开始循环,那么函数内部代码就会开始执行
- 最后⼀个yield执⾏完毕. 再次
__next__()程序报错- 生成器的标志:yield
- 生成器也是一种特殊的可迭代对象
def func():
print("111")
yield 222
print("333")
yield 444
gener = func()
ret = gener.__next__()
print(ret)
ret2 = gener.__next__()
print(ret2)
ret3 = gener.__next__()
# 最后⼀个yield执⾏完毕. 再次__next__()程序报错
print(ret3)
为了使生成器在循环过程中停止,可以通过条件return的方式,终止循环。从而程序避免报错。
def func():
count = 1
while True:
yield count
count +=1
if count == 100:
return
v1 = func()
for item in v1:
print(item)
生成器的标志:yield。不论这个yield函数是否被执行,他都是生成器函数
def func():
return 1
yield 1
v1 = func()
print(v1,type(v1))
本文详细介绍了Python中的装饰器,包括其定义、应用及带参数的装饰器,展示了如何在不修改原函数代码的情况下扩展功能。同时,文章还探讨了列表、集合和字典推导式,以及迭代器的概念和使用。通过实例,解释了生成器的运作机制及其在循环中的应用。此外,还提及了可迭代对象和迭代器在for循环中的作用。
20万+

被折叠的 条评论
为什么被折叠?



