装饰器的基础

学习前提: 作用域 + 函数的理解 + 闭包  【学习,理解】

代码编写原则: 对修改开放对扩展开放

装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。

装饰器的应用:经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。

装饰器作用:装饰器感觉就像是内部函数的调用应用,为已经存在的对象添加额外的功能。

原理讲解

基础原理讲解:不更改原来函数foo()的调用的基础上添加新的功能【假设每次都调用foo】

import  time
# 利用内部函数 来实现装饰器
def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
print("耗时", str(end - start))
return inner
def foo():
print('foo')
time.sleep(2)
def bar():
print('bar')
time.sleep(3)
# 这里就是装饰器,添加了新功能的同时还不影响原来的函数应用
foo = show_time(foo)
foo()
bar = show_time(bar)
bar()

Python的装饰器的实现:

@功能函数

import  time
def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
print("耗时", str(end - start))
return inner
@show_time # foo = show_time(foo)
def foo():
print('foo')
time.sleep(2)
@show_time # bar = show_time(bar)
def bar():
print('bar')
time.sleep(3)
foo()
bar()

装饰器之被装饰函数的参数:

参数在功能函数上添加, 装饰器参数对应的添加即可

import  time
def show_time(f):
def inner(*args):
start = time.time()
f(*args)
end = time.time()
print("耗时", str(end - start))
return inner
@show_time # foo = show_time(foo)
def foo(*args):
summary = 0
for i in args:
summary += i
print(summary)
time.sleep(2)
@show_time # bar = show_time(bar)
def bar():
print('bar')
time.sleep(3)
foo(2, 4, 4)
bar()

装饰器之装饰函数的参数:

多一层嵌套实现,代码更加灵活

# foo函数添加日志的写操作, bar函数不添加
import time def logger():
logger_format = '%F %T'
with open('log.txt', 'a+', encoding='utf-8') as f:
f.write('当前时间是:%s\n'% time.strftime(logger_format))
def log(flag = ''):
def show_time(f):
def inner(*args):
start = time.time()
f(*args)
end = time.time()
print("耗时", str(end - start))
if flag == 'true':
logger()
return inner
return show_time
@log('true') # 等价于@show_time('true') / show_time = show_time('true')
def foo(*args):
summary = 0
for i in args:
summary += i
print(summary)
time.sleep(2)
@log('') # 等价于@show_time('') / show_time = show_time('')
def bar():
print('bar')
time.sleep(3)
foo(2, 4, 4)
bar()

复杂装饰器

def makebold(fn):
def wrapper():
return "<b>" + fn() + "</b>"
return wrapper
def makeitalic(fn):
def wrapper():
return "<i>" + fn() + "</i>"
return wrapper
@makebold
@makeitalic
def hello():
return "hello world"
print(hello()) # <b><i>hello world</i></b>

Python学习---装饰器的学习1210的更多相关文章

  1. Python学习---装饰器/迭代器/生成器的学习【all】

    Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210

  2. Python装饰器模式学习总结

    装饰器模式,重点在于装饰.装饰的核心仍旧是被装饰对象. 类比于Java编程的时候的包装模式,是同样的道理.虽然概念上稍有不同但是原理上还是比较相近的.下面我就来谈一谈我对Python的装饰器的学习的一 ...

  3. python之循序渐进学习装饰器

    python装饰器的定义:在代码运行期间在不改变原函数定义的基础上,动态给该函数增加功能的方式称之为装饰器(Decorator) 装饰器的优点和用途: 1. 抽离出大量函数中与函数功能本身无关的的雷同 ...

  4. python基础 (装饰器,内置函数)

    https://docs.python.org/zh-cn/3.7/library/functions.html 1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使 ...

  5. python初级装饰器编写

    最近项目太忙好久没有学习python了,今天更新一下吧~~ 1.什么是python装饰器: 装饰器本质上是一个python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返 ...

  6. Python之装饰器、迭代器和生成器

    在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器.迭代器和生成器理解进行解释. 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思 ...

  7. python之装饰器、生成器、内置函数、JSON

    一.装饰器: 装饰器,器在这里的意思是函数,也就是装饰函数.作用是给其他函数添加新功能,它可以不改变原有的函数,原来的函数和原来一模一样,什么都不需要改变,只需要在函数外部加上调用哪个装饰器就可以了, ...

  8. Python的装饰器实例用法小结

    这篇文章主要介绍了Python装饰器用法,结合实例形式总结分析了Python常用装饰器的概念.功能.使用方法及相关注意事项 一.装饰器是什么 python的装饰器本质上是一个Python函数,它可以让 ...

  9. Python函数装饰器高级用法

    在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...

随机推荐

  1. SpringBoot集成WebSocket【基于STOMP协议】进行点对点[一对一]和广播[一对多]实时推送

    原文详细地址,有点对点,还有广播的推送:https://blog.csdn.net/ouyzc/article/details/79884688 下面是自己处理的一些小bug 参考原文demo,结合工 ...

  2. Types方法之isSameType-isSuperType-isSubType

    4.isSameType() 方法 /** * Is t the same type as s? */ public boolean isSameType(Type t, Type s) { retu ...

  3. 警告: Hessian/Burlap: 'com.github.pagehelper.Page' is an unknown class in WebappClassLoader

    项目中使用mybatis的分页插件pagehelper出现下面的警告 出现上面的警告,并不影响程序的运行.但是毕竟看着比较闹心. 使用debug进行代码根据发现,执行的过程中使用到了pagehelpe ...

  4. Java对zip格式压缩和解压缩

    Java对zip格式压缩和解压缩 通过使用java的相关类可以实现对文件或文件夹的压缩,以及对压缩文件的解压. 1.1 ZIP和GZIP的区别 gzip是一种文件压缩工具(或该压缩工具产生的压缩文件格 ...

  5. rvm的安装, 使用rvm, 安装ruby, 以及gem的使用 (转)

    http://blog.163.com/digoal@126/blog/static/1638770402012425111617904/ rvm 全称Ruby Version Manager,  确 ...

  6. Android6.0内核移植(2):kernel编译内核

    普通步骤是:用来编译整个Android源码 source build/envsetup.sh lunch sabresd_6dq-user make -j20 不过每次这样太繁琐,下面来单独编译ker ...

  7. C#基础笔记(第十二天)

    1.复习里氏转换:1).子类可以赋值给父类(如果有一个方法需要一个父类作为参数,我们可以传第一个子类对象)2).如果父类中装的是子类对象,则可以将这个父类强转为子类对象 is和as判断转换成功失败 P ...

  8. MyBatis中插入并返回主键

    开发过程中经常遇到需要插入一条数据,并且返回这条数据自增的主键,在MyBatis中只需要在mapper中添加keyProperty属性即可 在mapper中添加keyProperty属性 <in ...

  9. MySQL学习基础

    MySQL是被Sun公司收购了,所以也有热咖啡图标,不过MySQL的作者后来又做了一个MariaDB,小海豚图标,也很好用. MySQL学习: <MySQL网络数据库设计与开发>(电子工业 ...

  10. javascript window.opener的用法分析

    window.opener 返回的是创建当前窗口的那个窗口的引用 window.opener 的用法 window.opener 返回的是创建当前窗口的那个窗口的引用,比如点击了a.htm上的一个链接 ...