python進階(小白也能看懂)——裝飾器(一)
第四篇
1.函數基礎知識
談裝飾器前,先了解一下函數的基礎知識
- python中一切都是對象,函數也是對象,可以將一個函數賦值給另一個變量
- 函數可以嵌套,即在一個函數內部定義另一個函數
- 函數中可以將另一個函數作爲返回值返回
- 函數可以作爲參數傳給另一個函數
例子1.1
## 定義加法函數
def add_a_b(a, b):
print(a+b)
## 將該加法函數賦給t,這樣t也就是一個函數了,擁有加法功能
t = add_a_b
t(1,2)
"""
3
"""
例子1.2
# 在函數內部定義函數
def outer():
print("I'm in outer")
def inner():
print("I'm in inner of outer")
## 調用inner函數,且只能在ouer函數裏面調用inner
inner()
outer()
"""
I'm in outer
I'm in inner of outer
"""
inner()
"""
NameError: name 'inner' is not defined
"""
例子1.3
# 函數中將另一個函數作爲返回值返回
def outer():
print("I'm in outer")
def inner():
print("I'm in inner of outer")
## 調用inner函數,且只能在ouer函數裏面調用inner
return inner
# 這裏p相當於inner
p = outer()
p()
"""
I'm in outer
I'm in inner of outer
"""
例子1.4
import time
def runningtime(func):
def wrapper(*args, **kwargs):
## 添加計時功能
start = time.time()
func(*args, **kwargs)
interval = time.time() - start
print("運行完{}花費了{}秒".format(func.__name__, interval))
return wrapper
def add_a_b(a, b):
print(a+b)
## equipped_func接收從runningtime返回的函數
equipped_func = runningtime(add_a_b)
equipped_func(1000,54489)
"""
55489
運行完add_a_b花費了0.0009965896606445312秒
"""
2.不帶參數的裝飾器
所謂裝飾器是作用在函數身上的,主要是豐富函數的功能,並且非常方便。
假設我們寫了10000個函數,我們想測試運行每個函數所需要的時間,那麼可以用裝飾器添加計算時間的功能:
import time
from functools import wraps
## 定義裝飾器
def runningtime(func):
@wraps(func)
def wrapper(*args, **kwargs):
## 添加計時功能
start = time.time()
func(*args, **kwargs)
interval = time.time() - start
print("運行完{}花費了{}秒".format(func.__name__, interval))
return wrapper
@runningtime
def add_a_b(a, b):
print(a+b)
add_a_b(1000,54489)
"""
55489
運行完add_a_b花費了0.00099945068359375秒
"""
與例子1.4對比不難發現在函數前面加上@runningtime
的作用就相當於function = runningtime(function)
。
3.帶參數的裝飾器
from functools import wraps
import time
## 帶參數的裝飾器
def logging(logfile):
def runningtime(func):
@wraps(func)
def wrapper(*args, **kwargs):
## 添加計時功能
start = time.time()
func(*args, **kwargs)
interval = time.time() - start
print("運行完{}花費了{}秒".format(func.__name__, interval))
## 將日誌寫入日誌文件中
with open(logfile,'a') as f:
f.write(str(interval)+'\n')
return wrapper
return runningtime
@logging('test.txt')
def add_a_b(a, b):
print(a+b)
add_a_b(1000,54489)
"""
55489
運行完add_a_b花費了0.0030028820037841797秒
"""
在這裏,帶參數的裝飾器起的作用相當於function = logging('test.txt')(function)