我终于弄懂了Python的装饰器(四)
此系列文档:
四、装饰器的用法
通用装饰器(这里有一篇文档要补充)
如要制作通用装饰器(无论参数如何,您都可以将其应用于任何函数或方法),则只需使用*args, **kwargs:
def a_decorator_passing_arbitrary_arguments(function_to_decorate):
#包装器接受任何参数(这部分可以参考文档:+++++++补充文档+++++++++++++++)
def a_wrapper_accepting_arbitrary_arguments(*args, **kwargs):
print("Do I have args?:")
print(args)
print(kwargs)
function_to_decorate(*args, **kwargs)
return a_wrapper_accepting_arbitrary_arguments
@a_decorator_passing_arbitrary_arguments
def function_with_no_argument():
print("Python is cool, no argument here.")
function_with_no_argument()
#输出:
#Do I have args?:
#()
#{}
#Python is cool, no argument here.
@a_decorator_passing_arbitrary_arguments
def function_with_arguments(a, b, c):
print(a, b, c)
function_with_arguments(1,2,3)
#输出:
#Do I have args?:
#(1, 2, 3)
#{}
#1 2 3
@a_decorator_passing_arbitrary_arguments
def function_with_named_arguments(a, b, c, platypus="Why not ?"):
print("Do {0}, {1} and {2} like platypus? {3}".format(a, b, c, platypus))
function_with_named_arguments("Bill", "Linus", "Steve", platypus="Indeed!")
#输出:
#Do I have args ? :
#('Bill', 'Linus', 'Steve')
#{'platypus': 'Indeed!'}
#Do Bill, Linus and Steve like platypus? Indeed!
class Mary(object):
def __init__(self):
self.age = 31
@a_decorator_passing_arbitrary_arguments
def sayYourAge(self, lie=-3): # You can now add a default value
print("I am {0}, what did you think?".format(self.age + lie))
m = Mary()
m.sayYourAge()
#输出:
# Do I have args?:
#(<__main__.Mary object at 0xb7d303ac>,)
#{}
#I am 28, what did you think?
最佳做法:装饰器
注意:
- 装饰器是在Python 2.4中引入的,因此请确保您的代码将在> = 2.4上运行。
- 装饰器使函数调用变慢。(请记住这点)
- 您不能取消装饰功能。(有一些技巧,可以创建可以被删除的装饰器,但是没有人使用它们。)因此,一旦装饰了一个函数,就对所有代码进行了装饰。
- 装饰器包装函数,这会使它们难以调试。(这在Python> = 2.5时有所调整;请参见以下内容。)
该functools模块是在Python 2.5中引入的。
它包括函数functools.wraps(),该函数将修饰后的函数的名称,模块和文档字符串复制到其包装器中。
(有趣的事是:functools.wraps()也是一个装饰器!)
#为了进行调试,stacktrace将向您显示函数__name__
def foo():
print("foo")
print(foo.__name__)
#输出: foo
#使用装饰器时,输出的信息会变得凌乱,不再是foo,而是wrapper
def bar(func):
def wrapper():
print("bar")
return func()
return wrapper
@bar
def foo():
print("foo")
print(foo.__name__)
#输出: wrapper
# "functools" can help for that
import functools
def bar(func):
# We say that "wrapper", is wrapping "func"
# and the magic begins
@functools.wraps(func)
def wrapper():
print("bar")
return func()
return wrapper
@bar
def foo():
print("foo")
print(foo.__name__)
#outputs: foo
Python本身提供了一些装饰:property,staticmethod,等。
- Django使用装饰器来管理缓存和查看权限。
- 伪造的内联异步函数调用。
如何使用链式装饰器?
# 大胆的使用链式装饰器吧
def makebold(fn):
# The new function the decorator returns
def wrapper():
# Insertion of some code before and after
return "<b>" + fn() + "</b>"
return wrapper
# The decorator to make it italic
def makeitalic(fn):
# The new function the decorator returns
def wrapper():
# Insertion of some code before and after
return "<i>" + fn() + "</i>"
return wrapper
@makebold
@makeitalic
def say():
return "hello"
print(say())
#输出: <b><i>hello</i></b>
# This is the exact equivalent to
def say():
return "hello"
say = makebold(makeitalic(say))
print(say())
#输出: <b><i>hello</i></b>
现在,您可以暂时放下开心的心情,我们来动动脑筋,看看装饰器的高级用法。
原文链接:https://stackoverflow.com/questions/739654/how-to-make-a-chain-of-function-decorators
本文首发于BigYoung小站
我终于弄懂了Python的装饰器(四)的更多相关文章
- 我终于弄懂了Python的装饰器(一)
此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我终于弄懂了Python的装饰器(三) 4. 我终于弄懂了Python的装饰器(四) 一 ...
- 我终于弄懂了Python的装饰器(二)
此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我终于弄懂了Python的装饰器(三) 4. 我终于弄懂了Python的装饰器(四) 二 ...
- 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档
转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...
- 进阶Python:装饰器 全面详解
进阶Python:装饰器 前言 前段时间我发了一篇讲解Python调试工具PySnooper的文章,在那篇文章开始一部分我简单的介绍了一下装饰器,文章发出之后有几位同学说"终于了解装饰器的用 ...
- Python各式装饰器
Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...
- Python札记 -- 装饰器补充
本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...
- python基础——装饰器
python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...
- 【转】详解Python的装饰器
原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...
- 两个实用的Python的装饰器
两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...
随机推荐
- refs转发 React.forwardRef
2020-04-01 refs转发 前几天刚总结完ref&DOM之间的关系,并且想通了3种ref的绑定方式 今天总结一下refs转发 这是react中一直困扰我的一个点 示例: 输入: wor ...
- 【转载】自动化魔方求解器的Bug——选择合适的色彩空间
目录 1. 准备工作-- 2. RGB颜色空间 3. LAB色彩空间 4. YCrCb色彩空间 5. HSV色彩空间 Color spaces in OpenCV (C++ / Python) 几天前 ...
- CKA考试个人心得分享
考试相关准备: 真题:需要的私密: 网络:必须开启VPN,以便能访问国外网络,强烈建议在香港搭建相应FQ: 证件:考试需要出示含有拉丁文(英文)带照片的有效证件,相关有效证件参考(优先建议护照):ht ...
- django xadmin 配置过程
1.拷贝xadmin的一个下的一个xadmin文件夹放到项目里
- 在maven项目中使用Junit进行单元测试(一)
https://blog.csdn.net/ai_xue_xi/article/details/51819729 这篇文章相当的经典,最好使用的maven生成单元测试报告,不要在使用ant脚本生成单元 ...
- SpringSceurity(5)---短信验证码登陆功能
SpringSceurity(5)---短信验证码登陆功能 有关SpringSceurity系列之前有写文章 1.SpringSecurity(1)---认证+授权代码实现 2.SpringSecur ...
- python+opencv实现检测物体聚集区域
内容涉及:二值图像转换 / 检测连通区域面积 / 在原图上画框等 import cv2 import numpy as np for n in open('list.txt'): # list.txt ...
- 宿主机ping不通虚拟机,虚拟机能ping通宿主机问题
打开虚拟机管理器,点开设置=>网络,网络选的是NAT,所以宿主机不能直接ping能虚拟机!!! 问题描述 查看虚拟机ip, #ifconfig如下图: 宿主机ping虚拟机ip,无法通信,如下 ...
- SpringBoot-多数据源配置-Mysql-SqlServer-Oracle
Maven依赖 <!-- mysql的jdbc依赖 --> <dependency> <groupId>mysql</groupId> <arti ...
- Java 内存回收机制
当执行构造方法生成一个对象时,需要占用各种系统资源.当生成的对象不再使用时,就需要返回给操作系统,以免资源的泄露.在各种系统资源中,最常使用的就是内存.Java运行时系统通过垃圾收集周期性地释放无用对 ...