一、装饰器
装饰器,这个器就是函数的意思,连起来,就是装饰函数,装饰器本身也是一个函数,它的作用是用来给其他函数添加新功能,比如说,我以前写了很多代码,系统已经上线了,但是性能比较不好,现在想把程序里面每个函数都加一个功能,用来统计每个函数的运行时间是多少,找出来运行比较慢的函数,来优化代码,就需要添加一个新的功能,来统计程序的运行时间,那这样的话,就得修改每个函数了,需要改代码,但是代码特别多,改完了公司倒闭了,这时候装饰器就能排上用场了,它可以不改变原有的函数,原来的函数和原来一模一样,什么都不需要改变,只需要在函数外部加上调用哪个装饰器就可以了。so,装饰器的作用就是不改变原来函数的调用方式,不改变原来函数的代码,给它增加了一个新功能。但是不改变函数,给它增加新功能,那是不可能的,装饰器只不过是偷偷改变了原来的函数而已,而原来的函数不知不觉。
1、函数即变量
2、高阶函数
def fun(func1):
func1()
3、函数里面也可以嵌套函数。
高阶函数+函数嵌套 = 装饰器
import time
def say_hello():
print('hello')
print('hello')
time.sleep(1)
def timmer(func):
start_time = time.time()
func()
end_time = time.time()
print('程序运行的时间是: %s'%(end_time-start_time))
timmer(say_hello)
start_time = time.time()
func()
end_time = time.time()
print('程序运行的时间是: %s'%(end_time-start_time))
timmer(say_hello)
要想给原来的函数增加运行时间,需要将该函数作为变量,传入timmer()函数中;
但改变了原函数的调用方式
import time
def say_hello():
print('hello')
print('hello')
time.sleep(1)
def timmer(func):
def deco():
start_time = time.time()
func()
end_time = time.time()
print('程序运行的时间是: %s'%(end_time-start_time))
return deco
say_hello = timmer(say_hello) # 重新给say_hello赋值,但仍改变了原来的调用方式
say_hello() # 再次调用,则会改变原函数
def deco():
start_time = time.time()
func()
end_time = time.time()
print('程序运行的时间是: %s'%(end_time-start_time))
return deco
say_hello = timmer(say_hello) # 重新给say_hello赋值,但仍改变了原来的调用方式
say_hello() # 再次调用,则会改变原函数
在函数timmer()中,重新定义个函数,对原函数进行修改;
之后将timer()修改后的函数重新赋值给say_hello,再次调用say_hello() ,此时的say_hello已经为修改后的函数。
但仍改变了原来的调用方式
import time
def timmer(func):
def deco(*arg,**kwargs): # 统计函数的运行时间
start_time = time.time()
func(*arg,**kwargs)
end_time = time.time()
print('程序运行的时间是: %s'%(end_time-start_time))
return deco # 返回该函数名,注意无括号
@timmer # 指定使用哪个装饰器,等价于say_hello = timer(say_hello)
def say_hello():
print('hello')
time.sleep(1)
def timmer(func):
def deco(*arg,**kwargs): # 统计函数的运行时间
start_time = time.time()
func(*arg,**kwargs)
end_time = time.time()
print('程序运行的时间是: %s'%(end_time-start_time))
return deco # 返回该函数名,注意无括号
@timmer # 指定使用哪个装饰器,等价于say_hello = timer(say_hello)
def say_hello():
print('hello')
time.sleep(1)
@timmer
def say_name():
print('name is xiao')
time.sleep(2)
def say_name():
print('name is xiao')
time.sleep(2)
say_name()
say_hello()
@timmer 即为调用timmer这个装饰器,实现对原函数的修改,等价于say_hello = timer(say_hello)
再次调用原函数,即可
函数timmer就是装饰器,它把执行真正业务方法的func包裹在函数里面,看起来像bar被timmer装饰了。如果我们要定义函数时使用装饰器,避免使用赋值语句bar=timmer(bar),要用到装饰器的语法糖@,语法糖的意思就是一种语法的简写,它使代码看起来简洁,上面的bar=timmer(bar)和@timmter bar()是一样的。这样写的话,看起来也比较高大上一些。