python進階(小白也能看懂)——裝飾器淺談(一)

python進階(小白也能看懂)——裝飾器(一)

第四篇

1.函數基礎知識

談裝飾器前,先了解一下函數的基礎知識

  1. python中一切都是對象,函數也是對象,可以將一個函數賦值給另一個變量
  2. 函數可以嵌套,即在一個函數內部定義另一個函數
  3. 函數中可以將另一個函數作爲返回值返回
  4. 函數可以作爲參數傳給另一個函數

例子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)

參考

定義一個帶參數的裝飾器

發佈了84 篇原創文章 · 獲贊 113 · 訪問量 35萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章