装饰器需要了解以下三点知识:
1、函数即变量;
2、高阶函数;
3、嵌套函数;
所以首先先普及一下知识点:
变量定义x = 1,数据1读取到内存中,可以理解为存到一房间中,而x表示房间号;
函数定义,函数体部分读取到内存中,而函数名表示房间号;
def test():
print("in the test func")
所以本质上函数即变量
函数
匿名函数
匿名函数关键字lambda,一般的函数定义为def foo():会定义名字,匿名函数表示方式:
calc = lambda x:x*3
calc(3) 调用方式
高阶函数
高阶函数:把一个函数名当作实参传给另外一个函数或者返回值中包含函数名的函数就是高阶函数。
import time
def bar():
time.sleep(2)
print("inthebar")
def test(func):
start_time=time.time()
func()
stop_time=time.time()
print("thefuncruntimeis%s"%(stop_time-start_time))
test(bar)
此函数符合第一条规则,故为高阶函数。此程序目的是不改变bar函数源代码的情况下,增加了新功能,但改变了bar的调用方式。
def bar():
time.sleep(1)
print("inthebar")
def test(func):
print(time.localtime())
returnfunc
bar=test(bar)
bar()
此函数符合第二条规则,故也为高阶函数。此程序的目的是不改变bar的调用方式。
嵌套函数
嵌套函数是在一个函数中再定义一个函数
def foo():
print("inthefoo")
def bar():
print("inthebar")
bar()
foo()
即在一个函数体中,有关键字def定义另外一个函数。
装饰器
本质是函数,用来装饰其它函数。当某个项目中已经上线运行,有新需求需要对某些函数添加新功能,此时需要用到装饰器。
装饰器优势:
1、不需要修改被装饰函数的源代码;
2、不需求改变被修饰函数的调用方式;
装饰器示例:
import time
def timer(func):
def warpper(*args,**kwargs):
start_time=time.time()
func()
stop_time=time.time()
print("the func run time is %s" %(stop_time-start_time))
return warpper
@timer
def test():
time.sleep(2)
print("inthetest")
test()
装饰器为嵌套函数,注意必须有返回值否则报TypeError: 'NoneType' object is not callable的错误
@timer其实相当于test=timer(test),注意调用位置不同,test=timer(test)需在函数test之后调用
生成器
列表生成式:使代码更简洁
>>> a=[ i*2 for i in range(10)]
>>> a
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
更负责的列表生成式:在i*2的位置可以更替为函数func(i)
简单的生成器:
>>> a=( i*2 for i in range(10))
只是把[]变为(),此时a就是一个生成器,生成器只是存储了一个算法逻辑,数据只有在用到的时候才生成。当数据量很大时可以明显感觉到列表生成式耗时大,此时就需要用到生成器。
优点:节省内存
缺点:
1、只记录当前位置,并只有一个__next__()方法;
2、可以使用for循环依次生成访问;
3、只能一个一个访问,且不能回溯,访问数据不方便;
函数生成器,使用关键字yield,如程序:
def fib(max):
a,b=0,1
for i in range(max):
c=a+b
a=b
b=c
yield a
return done #return的值是异常时返回的内容
f=fib(4)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
如果使用__next__()方法调用,一旦超过数据长度,就会产生一个异常:
File "D:/PycharmProjects/untitled/20180409/斐波那契.py", line 32, in <module>
print(f.__next__())
StopIteration
可以使用以下程序替换f.__next__(),其中try捕捉报错类型并提示以优化程序:
while True:
try:
x=next(f)
print('f:',x)
except StopIteration as e:
print("Generatorreturnvalue:",e.value)
break
生成器应用实例:
import time
def costumer(name):
print("%s要吃包子了"%(name))
while True:
baozi=yield
print("%s包子来了,请%s来吃包子吧!"%(baozi,name))
return"没有包子了"
def producer(baozi_list):
client1=costumer("刘翔")
client2=costumer("田立三")
client1.__next__()
client2.__next__()
for i in baozi_list:
print("\033[1;31m正在做包子\033[0m")
time.sleep(3)
print("%s包子做好了"%(i))
client1.send(i)
client2.send(i)
baozi_list=["韭菜馅","猪肉大葱","三鲜馅"]
producer(baozi_list)
原文:http://blog.51cto.com/775110/2096615