Python学习笔记:装饰器
Python 装饰器的基本概念和应用
- 代码编写要遵循开放封闭原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:
- 封闭:已实现的功能代码块
- 开放:对扩展开发
装饰器是 Python 高阶函数的语法糖,可以为已经存在的对象添加额外的功能,比如:
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
Python 装饰器的基本实现
装饰器的例程:
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#File Name:04_decorator_simple.py
#Created Time:2019-01-09 15:24:38 import time def timefun(func):
# wrapped_fun 即为闭包, func 为要装饰的函数
def wrapped_fun():
start_time = time.time()
func()
end_time = time.time()
print("%s\t运行用时 %f s" % (func.__name__, end_time - start_time))
return wrapped_fun # 返回内部函数的引用 def foo1():
for i in range(10000):
pass @timefun # 相当于 foo = timefun(foo)
def foo():
for i in range(100000):
pass if __name__ == "__main__":
foo1 = timefun(foo1)
foo1()
foo()
装饰器例程
foo1 运行用时 0.000491 s
foo 运行用时 0.002976 s
装饰器例程的运行结果
运行过程分析见下图:

Python 装饰器实现的基础为闭包,其会在闭包中调用目标函数,关于闭馆的详细内容,请参考 Python 学习笔记:闭包
Python 装饰器的使用
多个装饰器
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#File Name:05_decorator_multi.py
#Created Time:2019-01-09 15:55:31 def make_body(func):
"""添加 body"""
def wrapped():
return "<b>" + func() + "</b>"
return wrapped def make_italic(func):
"""设置为斜体"""
def wrapped():
return "<i>" + func() + "</i>"
return wrapped # 相当于 make_body(make_italic(foo))
@make_body
@make_italic
def foo():
return "Hello World" def foo1():
return "Hello Python" if __name__ == "__main__":
print(foo())
foo1 = make_body(make_italic(foo1))
print(foo1())
01 多个装饰器
<b><i>Hello World</i></b>
<b><i>Hello Python</i></b>
01 多个装饰器——运行结果
多个装饰器的运行过程分析:

含有不定长参数
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#File Name:06_decorator_multi_var.py
#Created Time:2019-01-09 16:20:30 from time import ctime def timefun(func):
def wrapped_func(*args, **kwargs):
print("%s called at %s" % (func.__name__, ctime()))
print("wrapped_func: ", end="")
print(args, kwargs)
func(*args, **kwargs) # 拆包
return wrapped_func @timefun
def foo(a,b,*args, **kwargs):
print("foo: %s, %s, %s, %s" %(a, b, args, kwargs)) if __name__ == "__main__":
foo(1,2,3,4,5, tmp=2)
02 含有不定长参数
foo called at Wed Jan 9 16:32:48 2019
wrapped_func: (1, 2, 3, 4, 5) {'tmp': 2}
foo: 1, 2, (3, 4, 5), {'tmp': 2}
02 含有不定长参数——运行结果
带有返回值
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#File Name: 07_decorator_multi_retrun.py
#Created Time:2019-01-09 16:20:30 from time import ctime def timefun(func):
def wrapped_func(*args, **kwargs):
print("%s called at %s" % (func.__name__, ctime()))
print("wrapped_func: ", end="")
print(args, kwargs)
return func(*args, **kwargs) # 此处如何没有 return,则26行会输出 None
return wrapped_func @timefun
def foo(a,b,*args, **kwargs):
print("foo: %s, %s, %s, %s" %(a, b, args, kwargs))
return "Hello world!" if __name__ == "__main__":
print(foo(1,2,3,4,5, tmp=2))
03带有返回值
foo called at Wed Jan 9 16:38:05 2019
wrapped_func: (1, 2, 3, 4, 5) {'tmp': 2}
foo: 1, 2, (3, 4, 5), {'tmp': 2}
Hello world!
03带有返回值——运行结果
装饰器中设置外部变量
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#File Name: 08_decorator_outside_var.py
#Created Time:2019-01-09 16:20:30 def timefun_arg(outside_var="Hello"):
def timefun(func):
def wrapped_func(*args, **kwargs):
print("wrapped_func: %s" % outside_var)
return func(*args, **kwargs)
return wrapped_func
return timefun @timefun_arg()
def foo(a,b,*args, **kwargs):
return "foo: Hello world!" @timefun_arg("Python") # 相当于 foo1 = timefun_arg("Python")(foo1)
def foo1(a,b,*args, **kwargs):
return "foo1: Hello world!" if __name__ == "__main__":
print(foo(1,2,3,4,5, tmp=2))
print(foo1(1,2,3,4,5, tmp=2))
04 装饰器中设置外部变量
定义多层函数,相当于双层的装饰器。
wrapped_func: Hello
foo: Hello world!
wrapped_func: Python
foo1: Hello world!
04装饰器中设置外部变量——运行结果
类装饰器
#!/usr/bin/env python3
#-*- coding:utf-8 -*-
#File Name:09_decorator_class.py
#Created Time:2019-01-09 16:53:33 class Test(object):
def __init__(self, func):
print("******初始化******")
print("Called by %s." % func.__name__)
self.func = func def __call__(self):
return self.func() @Test # 相当于 foo = Test(foo)
def foo():
return "Hello world!" def foo1():
return "Hello python!" if __name__ == "__main__":
print(foo())
foo1 = Test(foo1)
print(foo1())
05 类装饰器
类对象借助 __call__() 魔术方法,即可实现相应的类装饰器
******初始化******
Called by foo.
Hello world!
******初始化******
Called by foo1.
Hello python!
05 类装饰器运行结果
Python学习笔记:装饰器的更多相关文章
- python学习笔记--装饰器
1.首先是一个很无聊的函数,实现了两个数的加法运算: def f(x,y): print x+y f(2,3) 输出结果也ok 5 2.可是这时候我们感觉输出结果太单一了点,想让代码的输出多一点看起来 ...
- Python学习笔记--装饰器的实验
装饰器既然可以增加原来函数的功能,那能不能改变传给原函数的参数呢? 我们实验一下,先上代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date ...
- Python学习笔记: 装饰器Decorator
介绍 装饰器是对功能函数的加强. 在原来的功能函数之外,另外定义一个装饰器函数,对原来的功能函数进行封装(wrapper)并在wrapper的过程中增加一些辅助功能. 应用场景 如下场景: 业务函数f ...
- python 学习分享-装饰器篇
本篇内容为偷窃的~哈哈,借用一下,我就是放在自己这里好看. 引用地址:http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html 第一步: ...
- python学习之装饰器-
python的装饰器 2018-02-26 在了解python的装饰器之前我们得了解python的高阶函数 python的高阶函数我们能返回一个函数名并且能将函数名作为参数传递 def outer() ...
- python学习day14 装饰器(二)&模块
装饰器(二)&模块 #普通装饰器基本格式 def wrapper(func): def inner(): pass return func() return inner def func(): ...
- Python学习 :装饰器
装饰器(函数) 装饰器作为一个函数,可以为其他函数在不修改原函数代码的前提下添加新的功能 装饰器的返回值是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等 ...
- python学习之-- 装饰器
高阶函数+嵌套函数 == 装饰器 什么是装饰器: 其实也是一个函数. 功能:为其他的函数添加附加功能 原则:不能修改被装饰的函数的源代码和调用方式 学习装饰器前首先要明白以下3条事项: 1:函数 即 ...
- 6月4日 python学习总结 装饰器复习
1. 装饰器的原理以及为什么要使用装饰器 在代码运行期间动态增加功能的方式,称之为"装饰器"(Decorator). 在不影响原代码结构的情况下为其添加功能 2. 装饰器的基本 ...
- 学习笔记——装饰器模式Decorator
装饰器模式,最典型的例子. 工厂新开了流水线,生产了手机外壳,蓝天白云花色.刚准备出厂,客户说还要印奶牛在上面,WTF…… 时间上来不及,成本也不允许销毁了重来,怎么办?弄来一机器A,专门在蓝天白云的 ...
随机推荐
- Hadoop实战:用Hadoop处理Excel通话记录
项目需求 有博主与家庭成员之间的通话记录一份,存储在Excel文件中,如下面的数据集所示.我们需要基于这份数据,统计每个月每个家庭成员给自己打电话的次数,并按月份输出到不同文件夹. 数据集 下面是部分 ...
- 10 - EmbeddedChannel-测试ChannelHandler链
方法 职责 writeInbound(Object... msgs) 将入站消息写入到EmbeddedChannel中 readInbound() 从EmbeddedChannel中读取一个入站消息, ...
- varnish pipe 和pass的区别分析
这两天在学习varnish,在学到vcl时,不理解pipe和pass的区别以及如何区分加以应用.通过两天的搜索,总算是理清了概念.现在记录在博客上跟大家分享. 当 vcl_recv 函数接收到请求时, ...
- 一、Spring-Data-Jpa 初体验(基于SpringBoot)
闲话少说,首先动起来(基于springboot+gradle): 1.引入依赖 dependencies { compile 'org.springframework.boot:spring-boot ...
- Hibernate笔记7--JPA CRUD
1.环境搭建,注意包结构的问题,src下建立名为META-INF的文件夹,放persistence.xml,位置放错,读不到会报错. <?xml version="1.0" ...
- Python开发环境Wing IDE搜索工具介绍
Wing IDE编辑器的搜索工具提供了一个基于友好GUI的搜索和替换工具. 某些情况下搜索可能会跨越整个文件,也有可能被限制到当前所选择的区域:可以区分大小写,也可以设置为不区分:可以被限制为只匹配整 ...
- Eucalyptus-利用镜像启动一个Centos实例
1.前言 使用kvm制作Eucalyptus镜像(Centos6.5为例)——http://www.cnblogs.com/gis-luq/p/3990795.html 上一篇我们讲述了如何利用kvm ...
- [AngularJS] $location 服务简介
参考博客: https://www.cnblogs.com/gaoruixin/p/6070502.html 简介 $location服务解析在浏览器地址栏中的URL(基于window.locati ...
- webstorm下载激活汉化
下载 官方下载地址:https://www.jetbrains.com/webstorm/ 激活 参考http://blog.csdn.net/it_talk/article/details/5244 ...
- php:生成的时间与本地电脑的时间不匹配
如题,在php中我发现在数据库中的时间跟电脑上的时间没有同步 本地时间: 数据库中,生成的时间: 很明显,时分秒是对应不上去的,那么我们只要在php.ini中找到 这里被注释掉了,那我们就改成这样: ...