装饰器

  本质上就是函数,功能是为其他函数添加附加功能
  原则:不修改被修饰函数的源代码,以及调用方式,即完全不能有任何改变
  装饰器 = 高阶函数+ 函数嵌套+ 闭包
高阶函数:函数作为参数或者返回一个函数
    闭包:必须要有函数嵌套,内部函数调用外部函数的变量

利用现有的姿势用高阶函数来实现装饰器的效果
  并没有更改foo函数的源代码,也实现了foo函数计算运算时间的附加功能
  但是却改变了foo函数的调用方式,以后都要用test(foo)才能调用
 import time
def foo():
time.sleep(3)
print('你好啊林师傅') def test(func):
# print(func)
start_time=time.time()
func()
stop_time = time.time()
print('函数运行时间是 %s' % (stop_time-start_time))
# foo()  
test(foo)  # 改变了调用方式了
  高阶函数的特性可以返回函数,可以实现不更改调用方式的问题
 def foo():
print('from the foo')
def test(func):
return func res=test(foo)
print(res)
res() foo=test(foo)
print(res)
foo()
  不修改foo源代码,不修改foo调用方式,但是函数多运行了一次,废物
 import time
def foo():
time.sleep(3)
print('来自foo') def timer(func):
start_time=time.time()
func()
stop_time = time.time()
print('函数运行时间是 %s' % (stop_time-start_time))
return func
foo=timer(foo)  #timer()运行了一次得出结果又赋值给foo
foo()        # foo()又重新运行一遍,,,,
  没有修改被修饰函数的源代码,也没有修改被修饰函数的调用方式,但是也没有为被修饰函数添加新功能
 def timer(func):
start_time=time.time()
return func
stop_time = time.time()
print('函数运行时间是 %s' % (stop_time-start_time)) foo=timer(foo)
foo()
  由此可见,高端函数仁义尽致依然做不到我们想要的那种透明而又不加大负担的效果因此需要装饰器


装饰器的框架
 def nnn(func):
def inner(*args,**kwargs):
"""在这里我做了一些什么操作"""
ret = func(*args,**kwargs)
"""在这里我又做了一些什么操作"""
return ret # 被装饰的函数的返回值
return inner  
@nnn
def big():
print("这是一个超级大源码")
big() # 本质上big() == nnn(big),但是装饰器不改变函数的调用方式,简化为big()

一个基本的计算运行时间的装饰器的例子
 import time
def timmer(func):
def wrapper(*args,**kwargs):
start_time = time.time()
res = func(*args,**kwargs)
stop_time = time.time()
print("函数的运行时间是%s" %(stop_time - start_time))
return res
return wrapper @timmer
def cal(l):
res = 0
for i in l:
time.sleep(0.1)
res += i
return res print(cal(range(20)))


带参数,返回值的装饰器使用
 import time
def timmer(func):
def wrapper(*args,**kwargs): # *args,**kwargs 模拟一切参数
start_time = time.time()
res = func(*args,**kwargs) # 实际上就是运行test() ,将test() 的结果拿出来赋值
# 和上面的wrapper的参数进行一一对应的解压
stop_time = time.time()
print("运行时间: %s " %(stop_time - start_time))
return res # 将赋值后的变返回值在通过wrapper再返回
return wrapper @timmer # test = timmer(test)
def test(name,age):
time.sleep(1)
print("我是天才,名字是%s ,年领是 %s" %(name,age))
return "我是天才返回值" # res = test("yangtuo",18) # 就是在运行wrapper
# print(res)
test("yangtuo",18) @timmer # test1 = timmer(test1)
def test1(name,age,gender):
time.sleep(1)
print("我是天才一号,名字是%s ,年领是 %s,性别是 %s" %(name,age,gender))
return "我是天才一号返回值" test1("shijieli",19,"man")

最新文章

  1. java21
  2. One Step github链接
  3. 完全开源Android网络框架 — 基于JAVA原生的HTTP框架
  4. NSDictionary 的有序性 (by the key in some rule)
  5. [转]比NPOI更討喜的Excel元件-EPPlus
  6. Android IOS WebRTC 音视频开发总结(六三)-- 2016国内IM云服务行业分析
  7. ThinkPHP 3.2.2跨控制器调用方法
  8. java 基本知识点学习
  9. 简易浏览器App webview
  10. linux grep 指定字符串的正则表达式
  11. ruby中__FILE__,$FILENAME,$PROGRAM_NAME,$0等类似变量的含义
  12. linux和sqlserver 2017的安装
  13. std::string 用法总结
  14. 洗礼灵魂,修炼python(28)--异常处理(2)—>运用异常
  15. Django - Jsonp、CORS
  16. Codeforces Global Round 2部分题解
  17. 【Luogu1912】【NOI2009】诗人小G(动态规划)
  18. iOS中响应者链条-触摸事件,hitTest方法坐标转换
  19. 成都Uber优步司机奖励政策(4月9日)
  20. 能用程序解决的问题绝不BB之租房篇章...

热门文章

  1. Java中try catch finally语句中含有return语句的执行情况(总结版)
  2. 腾讯云 ubuntu 上tomcat加载项目很慢
  3. Ionic app 上传图片之webApi接口
  4. *C#(WPF)--矩阵拖动和矩阵动画(拖动展开,不足动画效果)
  5. 支持自定义协议的虚拟仪器【winform版】
  6. [朴智妍][Lullaby]
  7. Word frequency program ver.1
  8. linux内核分析第二四学习报告
  9. 手工编程:hello world
  10. 用户模拟+spec