Python学习之路6 - 装饰器
2017-11-24 09:49
267 查看
装饰器定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能。
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
实现装饰器的知识储备:
1.函数即“变量”
2.高阶函数(满足下列条件之一就是高阶函数)
a:把一个函数名当作形参传给另一个函数(在不修改被装饰函数源代码的情况下修改其功能,但是调用方式变了)
b:返回值中包含函数名(不修改函数的调用方式,而修改函数功能)
3.嵌套函数
总结:
高阶函数+嵌套函数=>装饰器
现在三个知识点都已经解释过了,下面先实现一个原始版的装饰器。
原始版装饰器
接下来要写一个真实装饰器的实例
高级案例 -- 有参数装饰器
解决办法看下面案例。
高高级案例 -- 有返回值的装饰器
还有些时候我们需要给装饰器进行传参,给内部使用。解决方案看下面。
高高高级案例 -- 给装饰器传参
原则:1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方式
实现装饰器的知识储备:
1.函数即“变量”
2.高阶函数(满足下列条件之一就是高阶函数)
a:把一个函数名当作形参传给另一个函数(在不修改被装饰函数源代码的情况下修改其功能,但是调用方式变了)
b:返回值中包含函数名(不修改函数的调用方式,而修改函数功能)
3.嵌套函数
总结:
高阶函数+嵌套函数=>装饰器
1. 函数即变量
def bar(): #这里定义个函数 print('this is bar...') func = bar #将函数当变量一样赋值给func func() #这是func加上()就可以当函数用了这就是函数即变量。
2. 高阶函数
a:把一个函数名当做形参传给另一函数(在不修改被装饰函数源代码的情况下修改其他功能,但是调用方式变了)def bar(): print('this is bar...') bar() print('----------------------------------') def test(func): #在这里增加了功能 print(func) test(bar) #但是这里修改了调用方式b:返回值中包含函数名(不修改函数的调用方式,而修改函数功能)
def bar(): print('this is bar...') bar() print('----------------------------------') def test(func): #在这里增加了功能 print(func) return func #这里返回了函数地址 bar = test(bar) #将函数地址赋给一个变量,该变量和传入函数同名 bar() #这个变量加上括号,就可以当函数用了,同时又没有修改函数的调用方式
3. 嵌套函数
x = 1 def test1(): def test2(): def test3(): x = 3 print(x) test3() test2() test1()像这样在一个函数里面定义一个函数就叫做嵌套函数。
现在三个知识点都已经解释过了,下面先实现一个原始版的装饰器。
原始版装饰器
import time def test1(): #这里是被装饰的函数 time.sleep(1) print("this is test1....") def timer(func): #这里是装饰器函数 def deco(): strat = time.time() func() stop = time.time() print("run time %s" %(stop-strat)) return deco test1 = timer(test1) test1()这个装饰器的功能是测试test1函数的运行时间,deco函数有这个功能,所以这里其实我想运行的是deco函数,timer()函数的返回值也就是deco函数的地址;同时deco函数想要运行也要满足另一个条件,那就是需要调用timer函数,只有当timer函数运行的时候timer函数里面写的那些东西才会生效或者说被激活,deco函数才会定义成功。到此,test=timer(test1)这句代码的意思就是,先调用timer函数让deco函数的定义生效,同时将要被装饰的函数test1函数的地址传入,让deco函数里面的func函数生效,这是timer函数又会将deco函数的地址返回,并将地址赋值给test1这个变量。然后下面的test1后面加上括号,变成test1()的形式,就可以运行了。这样一个原始版的装饰器就写完了。
接下来要写一个真实装饰器的实例
import time def timer(func): def deco(): start_time = time.time() func() stop_time = time.time() print('the func run time is %s' %(stop_time-start_time)) return deco @timer #这里等于 test = timer(test),要装饰哪个函数,就在哪个函数前面加上这个 def test(): time.sleep(2) print('this is test...') test()上面这些都是一些比较基本的,如果装饰有参数的函数且参数的个数还都不一定怎么办呢?下面写一个高级案例 -- 有参数的装饰器
高级案例 -- 有参数装饰器
import time def timer(func): def deco(*args,**kwargs): #在这里接收参数 start_time = time.time() func(*args,**kwargs) stop_time = time.time() print('the func run time is %s' %(stop_time-start_time)) return deco @timer def test(name): time.sleep(2) print('this is test...',name) test('vector')如果原test函数里面有返回值,被装饰后我们打印它print(test()),结果会是none。因为这时的test=deco,而deco没有返回值,所以打印不出来。这样就会出现一个问题,如果test函数有返回值,test函数的一个功能(返回值)就会被弄丢了。
解决办法看下面案例。
高高级案例 -- 有返回值的装饰器
import time def timer(func): def deco(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print('the func run time is %s' %(stop_time-start_time)) return res #这里将func的返回值返回 return deco @timer def test(name): time.sleep(2) print('this is test...',name) return 'asdfasdfgdfgd' print(test('vector'))这样就可以打印出返回值了。
还有些时候我们需要给装饰器进行传参,给内部使用。解决方案看下面。
高高高级案例 -- 给装饰器传参
import time def timer(temp): print('this is ',temp) #这里是加进来的参数 def out(func): def deco(*args,**kwargs): start_time = time.time() res = func(*args,**kwargs) stop_time = time.time() print('the func run time is %s' %(stop_time-start_time)) return res return deco return out @timer('temp') def test(name): time.sleep(2) print('this is test...',name) return 'asdfasdfgdfgd' print(test('vector'))实际上就是整体又在外面加了一层内嵌函数。
相关文章推荐
- python学习之路-4 内置函数和装饰器
- Python学习之路-初学篇之初识装饰器
- python 学习之路(装饰器)
- python学习之路 六 :装饰器
- Python学习之路——变量赋值
- [ Tensorflow学习之路 ]——环境配置: tensorflow_CPU + ubuntu16.04(Linux) + Anaconda2-4.2.0 + python2
- Python学习之路——Linux基础之文件合并与文件归档
- Python学习之路4 - 文件操作&编码转换
- Python 装饰器学习以及实际使用场景实践
- Python学习(九)——匿名函数、装饰器、偏函数
- 王亟亟的Python学习之路(10)-匿名函数
- python cookbook 学习系列(一) python中的装饰器
- python学习之装饰器
- Python学习之路-历史以及开发环境
- 我的python学习之路----发送邮件(基于smtp)
- python学习之路——函数关于可变对象和不可变对象问题
- 我的Python学习之路之基本语法-输入输出
- Python学习之路【第一篇】-Python简介和基础入门
- 王亟亟的Python学习之路(四)-循环,条件,Range,list和tuple
- 我的python学习之路--with