装饰器

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

利用现有的姿势用高阶函数来实现装饰器的效果
  并没有更改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. 3.4《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——grepping(检索目标行命令)

    grep是检查文件内容最强大的工具之一,这也许不能代表什么,但这不是重点.的确,grep常用作动词,比如'你完全应该检索(grep)那个文件'. grep最常用于在文件中搜索子字符串.例如,我们在第三 ...

  2. JS-详解算数运算符"+"

    二元加法运算符“+”可以对两个数字做加法,也可以做字符串连接操作: 当两个操作数都是数字或都是字符串的时候,计算结果是显而易见的.然而对于其他情况来说,则要进行一些必要的类型转换,并且运算符的行为依赖 ...

  3. (原创)odoo在docker环境下无法备份

    odoo容器内置postgresql-client版本和数据库版本不一致,安装和数据库版本相同或者更高版本的客户端 参考:https://www.postgresql.org/download/lin ...

  4. sql储存过程in(多个参数)

    一.用sql函数 首先要创建一个截取字符串的函数,新建一个查询,把下面代码复制进去执行. 函数SqlitIn的第一个参数是储存过程要in的字符串,第二个参数是分隔符 CREATE function S ...

  5. EF 利用PagedList进行分页并结合查询 方法2

    微软提供了PagedList分页,相信大家在网上也能搜索一大堆关于pagedList用法的博客,论坛.但是,在使用的过程中一不小心,就会掉入pagedList某种常规用法的陷阱. 我所说的某种常规用法 ...

  6. [Python]Practice makes perfect

    Practice makes perfect 发音被儿子鄙视了.需要加强练习 以此自勉.

  7. .NET持续集成与自动化部署之路第三篇——测试环境到生产环境的一键部署策略(Windows)

    Jenkins测试环境到生产环境的一键部署策略(Windows) 一.前言     前面我们已经初步实现了开发集成环境.测试环境的持续集成(自动化构建.自动化测试.自动化部署).但生产环境自动化部署迟 ...

  8. OpenDaylight(Oxygen)安装feature出现错误的解决方案

    在使用OpenDaylight控制器时,初次进入karaf命令行下都需要先进行feature的安装 在使用Nitrogen版本(0.7.x)时,组件的安装可以类似 feature:install od ...

  9. 使用requests库提交multipart/form-data 格式的请求

    前言: Requests是用Python语言编写,基于urllib,采用Apache2 Licensed开源协议的HTTP库.它比urllib更加方便,可以节约我们大量的工作,完全满足HTTP测试需求 ...

  10. ResultSet集合查询字段名称(转载)

    转自:https://blog.csdn.net/song_litao/article/details/84751351 public List<String> getColumnName ...