装饰器

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

利用现有的姿势用高阶函数来实现装饰器的效果
  并没有更改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")

day14 装饰器的更多相关文章

  1. day14——装饰器

    day14 装饰器 装饰器本质就是闭包 开放封闭原则: 扩展是开放的(增加新功能),对源码是封闭的(修改已经实现的功能) 装饰器:用来装饰的工具 作用:在不改变源代码及调用方式的基础下额外增加新的功能 ...

  2. python学习day14 装饰器(二)&模块

    装饰器(二)&模块 #普通装饰器基本格式 def wrapper(func): def inner(): pass return func() return inner def func(): ...

  3. day14 装饰器模拟验证附加功能

    user_list=[ {'}, {'}, {'}, {'}, ] current_dic={'username':None,'login':False} def auth_func(func): d ...

  4. day14 带参装饰器、迭代器、生成器

    """ 今日内容: 1.带参装饰器及warps 2.迭代器 3.生成器 """ """ # 一.带参装饰器及w ...

  5. day14带参装饰器,迭代器,可迭代对象 , 迭代器对象 ,for迭代器 , 枚举对象

    复习 ''' 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 装饰 ...

  6. day-14带参装饰器、迭代器

    带参装饰器 通常,装饰器为被装饰的函数添加新功能,需要外界的参数  -- outer参数固定一个,就是func -- inner参数固定同被装饰的函数,也不能添加新参数 -- 可以借助函数的嵌套定义, ...

  7. python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器

    复习 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.返回内部函数对象---->  延迟执行, 开放封闭原则: 功能可以拓展,但源代 ...

  8. day14(带参装饰器,迭代器,生成器,枚举对象)

    一,复习 ''' 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 ...

  9. python27期day14:有参装饰器、多个装饰器装饰一个函数、递归、作业题

    1.有参装饰器:给装饰器添加一个参数.来控制装饰器的行为. @auth(参数) auth里层的函数名 = auth(参数) 被装饰的函数名 = auth里层的函数名(被装饰的函数名) 被装饰的函数名( ...

随机推荐

  1. phpstorm 2018.1.2的安装和破解

    1.什么是phpstorm? PhpStorm是一个轻量级且便捷的PHP IDE,其旨在提高用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时错误检查.但是phpstorm是商业软件, ...

  2. WebApi 接口返回值不困惑:返回值类型详解。IHttpActionResult、void、HttpResponseMessage、自定义类型

    首先声明,我还没有这么强大的功底,只是感觉博主写的很好,就做了一个复制,请别因为这个鄙视我,博主网址:http://www.cnblogs.com/landeanfen/p/5501487.html ...

  3. HAProxy 日志输出及配置

    正所谓,没有软件敢说没有bug,人无完人,software is  not perfect software.是软件就可能存在bug,那么如果出现bug,我们就要分析对我们业务的影响及可能如何避免bu ...

  4. HTML-JS 数组 内置对象

    [JS中的数组] 1.数组的基本概念? 数组是在内存空间中连续存储的一组有序数据的集合 元素在数组中的顺序,称为下标.可以使用下标访问数组的每个元素 2.如何声明一个数组 ① 使用字面量声明:var ...

  5. 从源码的角度看 React JS 中批量更新 State 的策略(上)

    在之前的文章「深入理解 React JS 中的 setState」与 「从源码的角度再看 React JS 中的 setState」 中,我们分别看到了 React JS 中 setState 的异步 ...

  6. C语言----数据类型(基础篇一)

    C语言的入门程序模板 #include <stdio.h> /*使用或者包含系统里面的程序*/ main() /*程序入口点*/ { /*起点*/ +; /*叫计算机执行的指令*/ } / ...

  7. Nginx 负载均衡的Cache缓存批量清理的操作记录

    1)nginx.conf配置 [root@inner-lb01 ~]# cat /data/nginx/conf/nginx.conf user www; worker_processes 8; #e ...

  8. 《Linux内核设计与实现》读书笔记四

    Chapter 3 进程管理 3.1 进程 进程就是处于执行期的程序(目标码存放在某种存储介质上),但进程并不仅仅局限于一段可执行程序代码.通常进程还要包含其他资源,像打开的文件,挂起的信号,内核内部 ...

  9. 20135337——Linux内核分析:第十七章 模块与设备

    第17章 模块与设备 设备类型:在所有 Unix 系统中为了统一普通设备的操作所采用的分类. 模块: Linux 内核中用于按需加载和卸载目标码的机制. 内核对象:内核数据结构中支持面向对象的简单操作 ...

  10. Oracle 和 SQLSERVER 重新获取统计信息的方法

    1. Oracle 重新获取统计信息的命令 exec dbms_stats.gather_schema_stats(ownname =>) # 需要修改 ownername options 指定 ...