此系列文档:

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小站

最新文章

  1. selenium获取多窗口句柄并一一切换至原窗口句柄(三个窗口)
  2. ssl_error_rx_record_too_long
  3. 关于string的练习题目
  4. 重新设置MySQL的root密码
  5. Java文档注释
  6. python 标准库 -- multiprocessing
  7. Linux之旅-ubuntu下搭建nodejs环境
  8. [leetcode]Decode Ways @ Python
  9. 分布式大数据多维分析(OLAP)引擎Apache Kylin安装配置及使用示例【转】
  10. Oracle行列转换小结
  11. 把html标签转换为实体 dhtmlspecialchars
  12. [转]caffe中solver.prototxt参数说明
  13. C#中WebBrowser控件的使用
  14. python自学之第一章 —— 变量
  15. Java中的String为什么是不可变的? — String源码分析
  16. 【bzoj1024】生日蛋糕
  17. 【OpenJudge9270】【Pku2440】【递推】DNA
  18. hibernate查询排序
  19. IOS开发之ZBarReaderView的使用
  20. Storm- 使用Storm实现词频汇总

热门文章

  1. Unable to open debugger port (127.0.0.1:55119): java.net.SocketException &quot;Socket closed&quot;
  2. Jmeter基础003----Jmeter组件之测试计划和线程组
  3. Linux系统使用Nmon监控及分析系统性能
  4. skynet 初步分析
  5. cb05a_c++_STL优先级队列priority_queue_less_greater
  6. 初步了解Windows7下部署Sonar
  7. IDEA自定义类注释和方法注释(自定义groovyScript方法实现多行参数注释)
  8. TensorFlow中读取图像数据的三种方式
  9. JDBC知识点总结
  10. python多线程+生产者和消费者模型+queue使用