此系列文档:python
如要制做通用装饰器(不管参数如何,您均可以将其应用于任何函数或方法),则只需使用*args, **kwargs
:post
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?
注意:ui
该functools
模块是在Python 2.5中引入的。
它包括函数functools.wraps()
,该函数将修饰后的函数的名称,模块和文档字符串复制到其包装器中。调试
(有趣的事是:functools.wraps()
也是一个装饰器!)code
#为了进行调试,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
,等。orm
# 大胆的使用链式装饰器吧 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/que...
本文首发于 BigYoung小站