python3 装饰器全解
本章结构:
1.理解装饰器的前提准备
2.装饰器:无参/带参的被装饰函数,无参/带参的装饰函数
3.装饰器的缺点
4.python3的内置装饰器
5.本文参考
理解装饰器的前提:1.所有东西都是对象(函数可以当做对象传递) 2.闭包
闭包的概念:
1)函数嵌套
2)内部函数使用外部函数的变量
3)外部函数的返回值为内部函数
下面写一个最为简单的闭包的例子:
def test(name):
def test_in():
print(name)
return test_in func = test('whyz')
func()
装饰器的原型:
import time
def showtime(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) return wrapper def foo():
print('foo..')
time.sleep(3) foo = showtime(foo)
foo()
不带参数的装饰器:(装饰器,被装饰函数都不带参数)
import time
def showtime(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) return wrapper @showtime #foo = showtime(foo)
def foo():
print('foo..')
time.sleep(3) @showtime #doo = showtime(doo)
def doo():
print('doo..')
time.sleep(2) foo()
doo()
带参数的被装饰的函数
import time
def showtime(func):
def wrapper(a, b):
start_time = time.time()
func(a,b)
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) return wrapper @showtime #add = showtime(add)
def add(a, b):
print(a+b)
time.sleep(1) @showtime #sub = showtime(sub)
def sub(a,b):
print(a-b)
time.sleep(1) add(5,4)
sub(3,2)
带参数的装饰器(装饰函数),
实际是对原有装饰器的一个函数的封装,并返回一个装饰器(一个含有参数的闭包函数),
当使用@time_logger(3)调用的时候,Python能发现这一层封装,并将参数传递到装饰器的环境去
import time
def time_logger(flag = 0):
def showtime(func):
def wrapper(a, b):
start_time = time.time()
func(a,b)
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) if flag:
print('将此操作保留至日志') return wrapper return showtime @time_logger(2) #得到闭包函数showtime,add = showtime(add)
def add(a, b):
print(a+b)
time.sleep(1) add(3,4)
类装饰器:一般依靠类内部的__call__方法
import time
class Foo(object):
def __init__(self, func):
self._func = func def __call__(self):
start_time = time.time()
self._func()
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) @Foo #bar = Foo(bar)
def bar():
print('bar..')
time.sleep(2) bar()
使用装饰器的缺点:
1.位置错误的代码->不要在装饰器之外添加逻辑功能
2.不能装饰@staticmethod 或者 @classmethod已经装饰过的方法
3.装饰器会对原函数的元信息进行更改,比如函数的docstring,__name__,参数列表:
下面对装饰器第第三个缺点进行剖析,
import time
def showtime(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) return wrapper @showtime #foo = showtime(foo)
def foo():
print('foo..')
time.sleep(3) def doo():
print('doo..')
time.sleep(2) print(foo.__name__)
print(doo.__name__)
结果为:
wrapper
doo
由此可以看出,装饰器会对原函数的元信息进行更改,可以使用wraps,进行原函数信息的添加
注解:wraps本身也是一个装饰器,他能把函数的元信息拷贝到装饰器函数中使得装饰器函数与原函数有一样的元信息
以下是一个wraps的例子:
import time
from functools import wraps
def showtime(func): @wraps(func)
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print('spend is {}'.format(end_time - start_time)) return wrapper @showtime #foo = showtime(foo)
def foo():
print('foo..')
time.sleep(3) def doo():
print('doo..')
time.sleep(2) print(foo.__name__)
print(doo.__name__)
结果为:
foo
doo
常用的内置装饰器:1.staticmethod: 类似实现了静态方法 注入以后,可以直接 : 类名.方法
2.property:经过property装饰过的函数 不再是一个函数,而是一个property,类似实现get,set方法
@property
def width(self):
return self.__width @width.setter
def width(self, newWidth):
self.__width = newWidth
3.classmethod: 与staticmethod很相似,貌似就只有这一点区别:
第一个参数需要是表示自身类的 cls 参数,
可以来调用类的属性,类的方法,实例化对象等。
本文参考:
1.https://www.cnblogs.com/vamei/archive/2013/02/16/2820212.html
2.https://www.cnblogs.com/wupeiqi/articles/4980620.html
3.https://www.cnblogs.com/yuanchenqi/articles/5830025.html
4.https://blog.csdn.net/mdzzname/article/details/78702440
python3 装饰器全解的更多相关文章
- jquery系列教程1-选择器全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件 ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
- 净心诀---python3装饰器
python3装饰器 装饰器作用 简单理解:可以为已有函数添加额外功能 例: 已有2个函数如下 def MyFunc1(): print("This is a print function1 ...
- Python全栈开发之8、装饰器详解
一文让你彻底明白Python装饰器原理,从此面试工作再也不怕了.转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5486253.html 一.装饰器 装饰器可以使函数执 ...
- Python装饰器的解包装(unwrap)
在Python 3.4 中,新增一个方法unwrap,用于将被装饰的函数,逐层进行解包装. inspect.unwrap(func, *, stop=None) unwrap方法接受两个参数:func ...
- python3 装饰器应用举例
[引子] python 中的装饰器是oop(面向对象编程)设计模式.之装饰器模式的一个应用.由于有语法糖衣的缘故.所以写起来也更加方便 [从一个比较经典的应用场景来讲解装饰器] 有过一定编程经历的工程 ...
- python3 装饰器
#Author by Andy#_*_ coding:utf-8 _*_#装饰器的原则及构成:# 原则:# 1.不能修改被装饰函数的源代码.# 2.不能修改被装饰函数的调用方式.# 3.不能改变被装饰 ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- python之装饰器详解
这几天翻看python语法,看到装饰器这里着实卡了一阵,最初认为也就是个函数指针的用法,但仔细研究后发现,不止这么简单. 首先很多资料将装饰器定义为AOP的范畴,也就是Aspect Oriented ...
随机推荐
- MVC中页面传值方式总结
MVC中的页面传值,通常指Controller和view之间的数据传递,经常用到的有几种方式,总结如下: 一.Controller----------->View(控制器传到视图) 1.View ...
- asdfasdfasdfasdf
- WCF webHttpBinding协议上传接收文件
一般情况下wcf用webHttpBinding协议最多的场景就是前后端Json交互,会比较轻量级. 接收上传的文件也可以,不过要自己解析处理. 前端HTML很简单: <input type=&q ...
- synchronized实现可见性
JMM关于synchronized的两条规定: 1)线程解锁前,必须把共享变量的最新值刷新到主内存中 2)线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中重新获取最新的值 ( ...
- babel使用入门以及使用webpack+babel来"编译"你的JS代码
Babel是一个广泛使用的转码器,可以将ES6代码转为ES5,从而在现有的环境中执行. 这是一个开端,以后遇到问题,也会持续记录. 一.babel配置 官网有更详细的配置教程:https://www. ...
- 使用dom4j处理xml操作xml数据
使用dom4j处理xml操作xml数据 示例代码: public class TestDom4j { public static void main(String[] args) { String x ...
- css伪类和伪元素的区别,:before和::before的区别
伪类用于选择DOM树之外的信息,或是不能用简单选择器进行表示的信息.前者包含那些匹配指定状态的元素,比如:visited,:active:后者包含那些满足一定逻辑条件的DOM树中的元素,比如:firs ...
- Mysql InnoDB的四个事务隔离级别和(分别逐级解决的问题)脏读,不可重复读,虚读
MySqlInnoDB的事务隔离级别有四个:(默认是可重复读repeatable read) 未提交读 read uncommit : 在另一个事务修改了数据,但尚未提交,在本事务中SELECT语句可 ...
- 【vue】vue的路由权限管理
前言: 最近闲来无事浏览各种博客,看到了一个关于路由权限的管理,觉得很有用,针对那个博客,准备自己写一个demo. 实现: 路由大致分为用户路由<特定用户才能浏览>和基本路由<所有用 ...
- Vue 框架-09-初识组件的应用
Vue 框架-09-初识组件的应用 今天的第一个小实例,初步使用组件: 在 app.js 中定义模板组件,在 html 文件中使用自定义标签来显示 js 文件中定义的 html 代码块 比如说,下面定 ...