装饰器

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

利用现有的姿势用高阶函数来实现装饰器的效果
  并没有更改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. java計算年齡的工具類

    整理一篇Java計算年齡的工具類,方便實用 public static int getAgeByBirth(String birthday) throws ParseException { // 格式 ...

  2. vba基础知识

    VBA中dim,static和public,private的区别 转载的文章:出自 红袖的博客http://blog.sina.com.cn/19850701xx     1.Public和Priva ...

  3. odoo之页面跳转

    击备注时,会由备注id带出他的内容 customer.requirement这是备注内容表 def sale_requirements_change(self, cr, uid, ids, requi ...

  4. Sql Server插入数据并返回自增ID,@@IDENTITY,SCOPE_IDENTITY和IDENT_CURRENT的区别(转载)

    预备知识:SQL Server的IDENTITY关键字IDENTITY关键字代表的是一个函数,而不是identity属性.在access里边没有这个函数,所以在access不能用这个语句.语法:ide ...

  5. CDH hive-1.1.0-cdh5.10.0 安装

    又重新安装Hive,记录一下吧: hadoop早已经装上了. cdh5的hive下载地址: http://archive.cloudera.com/cdh5/cdh/5/ 下载文件:hive-1.1. ...

  6. 数据库日志——mysql与Oracle的日志

    一.MySQL 在数据同步中用的比较多的是MySQL的binlog 1.bin-log简介 它记录了所有的DDL和DML(除了数据查询语句,select与show不记录)语句,以事件形式记录,还包含语 ...

  7. 面试2——java基础3

    21.Http请求的get和post的区别? get:从 指定的资源请求数据.请注意,查询字符串(名称/值对)是在 GET 请求的 URL 中发送的 post:向指定的资源提交要被处理的数据.请注意, ...

  8. Linux中2>&1使用

    转:2>&1使用 一 相关知识 1)默认地,标准的输入为键盘,但是也可以来自文件或管道(pipe |).2)默认地,标准的输出为终端(terminal),但是也可以重定向到文件,管道或后 ...

  9. 2018年高教社杯全国大学生数学建模竞赛C题解题思路

    题目 C题   大型百货商场会员画像描绘 在零售行业中,会员价值体现在持续不断地为零售运营商带来稳定的销售额和利润,同时也为零售运营商策略的制定提供数据支持.零售行业会采取各种不同方法来吸引更多的人成 ...

  10. BugkuCTF 计算器

    前言 写了这么久的web题,算是把它基础部分都刷完了一遍,以下的几天将持续更新BugkuCTF WEB部分的题解,为了不影响阅读,所以每道题的题解都以单独一篇文章的形式发表,感谢大家一直以来的支持和理 ...