在理解裝飾器的概念前,我們首先看一下function和inner function在python中的含義。
成都創新互聯是專業的瀾滄網站建設公司,瀾滄接單;提供成都網站設計、做網站,網頁設計,網站設計,建網站,PHP網站建設等專業做網站服務;采用PHP框架,可快速的進行瀾滄網站開發網頁制作和功能擴展;專業做搜索引擎喜愛的網站,專業的做網站團隊,希望更多企業前來合作!
function:在python中,function就像其他對象一樣,可以當做參數或返回值。
inner function:一個函數A(inner function)定義在另一個函數B中。函數A就叫做inner function。
# 函數用做參數
def hello():
print("hello")
def welcome():
print("Welcome")
def say_something(func):
func()
# 函數add在函數cal中定義,并且用做返回值
def cal():
def add(a,b):
print(a+b)
return add
注意:此時add不能直接被外界調用,因此此時內部函數還未定義。但可以通過cal將add的引用返回,用于在將來調用。
decorator:封裝了一個函數,并且改變了其行為
裝飾器本質上,是將要被裝飾的函數作為參數,并且返回一個包裹其的、內部定義的函數。如下所示:my_decorator返回了wrapper的引用,用于將在將來執行。
def hello():
print("hello")
def my_decorator(func):
def wrapper():
print("before func work")
func()
print("after func work")
return wrapper
hello_d = my_decorator(hello)
hello_d()
"""
before func work
hello
after func work
"""
hello_d便是經過my_decorator裝飾的函數。我們明顯發現,過程有些復雜,為了簡化步驟,python提供了@decorator
的語法糖。
下面,我們使用@decorator
達到同樣的目的。
@my_decorator
def hello():
print("hello")
def my_decorator(func):
def wrapper():
print("before func work")
func()
print("after func work")
return wrapper
hello()#與hello = my_decorator(hello)作用相同
"""
before func work
hello
after func work
"""
在裝飾器中,wrapper的命名可自定義。
觀察上面的例子,由于hello被my_decoratorx裝飾過,此時在python shell查看hello的__name__,發現
這對我們來說,不是有用的信息,為了“正確”顯示,使用@functools.wrap(func)
import functools
@my_decorator
def hello():
print("hello")
def my_decorator(func):
@functools.wrap(func)
def wrapper():
print("before func work")
func()
print("after func work")
return wrapper
然后便可以達到和裝飾器裝飾前同樣的效果:
# do twice
def do_twice(func):
@functools.wraps(func)
def wrapper(*args,**kwargs):
func(*args,**kwargs)
func(*args,**kwargs)
return wrapper
# timer
def timer(func):
@functools.wraps(func)
def wrapper_timer(*args, **kwargs):
start_time = time.perf_counter()
value = func(*args, **kwargs)
end_time = time.perf_counter()
run_time = end_time - start_time
print(f"Finished {func.__name__} in {run_time:.4f} seconds")
return value
return wrapper_timer
@timer
def waste_time(num):
for _ in range(num):
sum([i **2 for i in range()])
waste_time(1000)
# flask check user login
def login_required(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if g.user is None:
return redirect(url_for('login',next=request.url))
return func(*args, **kwargs)
return wrapper
@app.route('/secret')
@login_required
def secret():
...
decorator用于“包裹”一個函數,改變其行為。
在裝飾器的wrapper中并不一定要執行該函數,也可以保留函數的引用,用于插件的注冊。
realpython
網站欄目:python中的decorator裝飾器(上)
分享地址:http://m.kartarina.com/article4/dsogjie.html
成都網站建設公司_創新互聯,為您提供微信公眾號、自適應網站、云服務器、外貿網站建設、App開發、網站設計
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯