此系列檔案:
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本身提供了一些裝飾: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小站
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/89925.html
標籤:Python
上一篇:Python學習作業一
下一篇:學習celery時遇到的坑
