此系列文档:

1. 我终于弄懂了Python的装饰器(一)

2. 我终于弄懂了Python的装饰器(二)

3. 我终于弄懂了Python的装饰器(三)

4. 我终于弄懂了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本身提供了一些装饰:propertystaticmethod,等。

  • 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的装饰器(四)的更多相关文章

  1. 我终于弄懂了Python的装饰器(一)

    此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我终于弄懂了Python的装饰器(三) 4. 我终于弄懂了Python的装饰器(四) 一 ...

  2. 我终于弄懂了Python的装饰器(二)

    此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我终于弄懂了Python的装饰器(三) 4. 我终于弄懂了Python的装饰器(四) 二 ...

  3. 理解Python中的装饰器//这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档

    转自:http://www.cnblogs.com/rollenholt/archive/2012/05/02/2479833.html 这篇文章将python的装饰器来龙去脉说的很清楚,故转过来存档 ...

  4. 进阶Python:装饰器 全面详解

    进阶Python:装饰器 前言 前段时间我发了一篇讲解Python调试工具PySnooper的文章,在那篇文章开始一部分我简单的介绍了一下装饰器,文章发出之后有几位同学说"终于了解装饰器的用 ...

  5. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  6. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  7. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

  8. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  9. 两个实用的Python的装饰器

    两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...

随机推荐

  1. MyBatis运行流程及入门第一个程序

    1. mybatis是什么? MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并 ...

  2. 总结:修改相关postgres用户密码

    1.修改linux系统postgres用户的密码 PostgreSQL会创建一个默认的linux用户postgres,修改该用户密码的方法如下: 步骤一:删除用户postgres的密码 sudo  p ...

  3. 《刻意练习之C#》-0016- C#预处理器指令

    预处理指令 这些指令/命令不会转换为可执行代码,但会影响编译过程的各个方面:列如,可以让编译器不编译某一部分代码等. C#中主要的预处理指令 #define和#undef #define指令定义: # ...

  4. <WP8开发学习笔记>获取手机的常用型号(如Lumia920,而非RM-822)

    之前WP7时代可以用API获得WP手机的型号如lumia510,但是到了WP8后用APi只能获得硬件版本号了如RM-822,这种型号可以让我们更详细的了解具体的硬件版本,比如国行和港行,设备版本号不一 ...

  5. HTML常用API(位置信息、音频视频)

    感谢:链接(讲解的很详细) 位置信息 1.代码: <script type="text/javascript"> navigator.geolocation.getCu ...

  6. shutil模块的使用

    shutil模块 高级的文件,文件夹,压缩包处理模块 shutil.copyfileobj(fsrc,fdst,length) 将文件内容拷贝到另外一个文件中,可以部分.fdst目标length长度( ...

  7. LR脚本信息函数-lr_get_vuser_ip

    lr_get_vuser_ip 返回Vuser的IP地址. char * lr_get_vuser_ip(); lr_get_vuser_ip函数返回Vuser的IP地址. 当执行IP欺骗时,每个Vu ...

  8. 深度解密 Go 语言之 sync.map

    工作中,经常会碰到并发读写 map 而造成 panic 的情况,为什么在并发读写的时候,会 panic 呢?因为在并发读写的情况下,map 里的数据会被写乱,之后就是 Garbage in, garb ...

  9. 十六进制颜色码及其表示-(6 digit color code)

    我们知道对于RGB颜色系统,颜色是由三个256位的十进制数值表示的: (R:0-255,G:0-255,B:0-255) 那么一个三元组可以确定一种颜色. 然而,在很多配置文件中颜色并不是直接用十进制 ...

  10. VMWare12安装CentOS7操作系统并搭建GitLab环境【1】

    查看了网上这方面的资料,发现都比较复杂,自己到官方网站上查询,并实际动手安装了一下,发现还是比较简单的. 1.VMWare Workstation 12 Professinal安装 2.安装64位Ce ...