装饰器函数
装饰器的主要功能:在不改变函数调用方式的基础上在函数的前、后添加功能。
装饰器的固定格式:
#装饰器定式
#例子1:
def wrapper(func):
def inner(*args,**kargs):
ret = func(*args,**kargs)
return ret
return inner
@wrapper #语法糖 可用代替 qqxing =wrapper(qqxing)
def qqxing():
print(123)
ret = qqxing() #相当于执行inner
-----------------------------------------------------------
#例子2:
import time
def wrapper(func): #装饰器函数,f是被装饰的函数
def inner(*args,**kwargs):
#在被装饰函数之前要做的事
ret = func(*args,**kwargs) #被装饰的函数
#在被装饰函数之后要做的事
return ret
return inner
@wrapper #语法糖
def func(a,b):
time.sleep(0.01)
print("你好",a,b)
func("小黑","小白")
带参数的装饰器
#假如你有成千上万个函数使用了一个装饰器,现在你想把这些装饰器都取消掉,你要怎么做?
# 一个一个的取消掉? 没日没夜忙活3天。。。
# 过两天你领导想通了,再让你加上。。。
#方法一:
#适用少量装饰器,每次需要更改每一个语法糖后面的变量值,比较麻烦。第二种是进阶方法
def outer(flag):
def timer(func): def inner(*args,**kwargs): if flag: print('''执行函数之前要做的''') re = func(*args,**kwargs) if flag: print('''执行函数之后要做的''') return re return inner return timer @outer(False) #在语法糖后面加一个布尔值,当需要执行装饰器内部的函数就写成True,否则False def func(): print(111) func()
-------------------------------------------------------------------
#方法二:
#是第一种方法的进阶版,只需要更改FLAG变量就可以控制所有的装饰器是否执行,适用于写了很多的装饰器
import time
FLAG=False #只需要改变FLAG的变量
def outer(flag):
def timmer(func):
def inner(*args,**kwargs):
if flag:
start = time.time()
ret =func(*args,**kwargs)
end=time.time()-start
print(end)
return ret
else:
ret =func(*args,**kwargs)
return ret
return inner
return timmer
@outer(FLAG)
def ceshi():
time.sleep(0.2)
print('测试成功')
ceshi()
@outer(FLAG)
def ceshi2():
time.sleep(0.3)
print('测试成功')
ceshi2()
多个装饰器装饰同一个函数
def wrapper1(func): def inner(): print('wrapper1 ,before func') func() print('wrapper1 ,after func') return inner def wrapper2(func): def inner(): print('wrapper2 ,before func') func() print('wrapper2 ,after func') return inner @wrapper2 @wrapper1 def f(): print('in f') f()
#结果:
wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func
执行过程:
迭代器函数
可迭代与迭代器的区别
可迭代:在Python中如果一个对象有__iter__( )方法或__getitem__( )方法,则称这个对象是可迭代的(Iterable);其中__iter__( )方法的作用是让对象可以用for ... in循环遍历,__getitem__( )方法是让对象可以通过“实例名[index]”的方式访问实例中的元素。换句话说,两个条件只要满足一条,就可以说对象是可迭代的。显然列表List、元组Tuple、字典Dictionary、字符串String等数据类型都是可迭代的。当然因为Python的“鸭子类型”,我们自定义的类中只要实现了__iter__( )方法或__getitem__( )方法,也是可迭代的
迭代器:在Python中如果一个对象有__iter__( )方法和__next__( )方法,则称这个对象是迭代器(Iterator);其中__iter__( )方法是让对象可以用for ... in循环遍历,__next__( )方法是让对象可以通过next(实例名)访问下一个元素。注意:这两个方法必须同时具备,才能称之为迭代器。列表List、元组Tuple、字典Dictionary、字符串String等数据类型虽然是可迭代的,但都不是迭代器,因为他们都没有next( )方法。
生成器函数
#只含有yeild关键字的函数是生成器函数
#yeild不能和return共用且需要写在函数内部
def generate():
print(1)
yield 'a'
#生成器函数:执行之后会得到一个生成器作为返回值
g=generate() #g就是生成器
print(g)
ret=g.__next__()
print(ret)
#结果:
<generator object generate at 0x037F1F70>
1
a
#生产两百万件衣服 def closes(): for i in range(200): yield'close%s'%i g=closes() for i in range(20): ret=g.__next__() print(ret) for i in range(20): ret = g.__next__() print(ret)
生成器函数进阶:
def generate(): print(123) content=yield print('====',content) print(456) yield 2 g=generate() ret=g.__next__() print(ret) ret = g.send('hello') #send获取下一个值的效果和next效果一致 #只是在获取下一个值的时候,给上一个yield的位置传递一个数据
print(ret)
#结果:
123
None
==== hello
456
2
#使用send的注意事项:
#第一个使用生成器的时候,是用next获取下一个值
#最后一个yield不能接受外部的值
#获取移动平均值 def average(): sum=0 count=0 avg=0 while True: num=yield avg sum =sum+num count=count+1 avg=sum/count
生成器表达式和列表推导式
egg_list=[] #for循环 for i in range(10): egg_list.append("鸡蛋%s"%i) print(egg_list) egg_list=['鸡蛋%s'%i for i in range(10)]#列表推导式 print(egg_list)
#生成器表达式 g=(i for i in range(10)) print(g) for i in g: print(i) g=(i*i for i in range(10)) print(g) for i in g: print(i)
#[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] #遍历之后挨个处理
#[满足条件的元素相关的操作 for 元素 in 可迭代的数据类型 if 元素相关的条件 ] #筛选功能 #30以内所有能被3整除的数 ret=[i for i in range(30) if i%3==0] print(ret) #30以内所有能被3整除的数的平方 ret=[i*i for i in range(30) if i%3==0] print(ret) #找出嵌套列表中名字含有两个'e'的所有名字 names =[['hhhh','rrr','hhhh','eettr','tryee'],['sfsgg','eerfgsg','gertfre','atarw','sarar']] ret=[name for lst in names for name in lst if name.count('e')==2] print(ret)
面试题:
#面试题 def add(n,i): return n+i def test(): for i in range(4): yield i g=test() for n in [1,10]: g=(add(n,i) for i in g) n=1 g = (add(n, i) for i in g) n=10 g = (add(n, i) for i in (add(n, i) for i in g)) print(list(g))