此係列文檔: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小站