關於python中裝飾器的定義,我們這裡參考廖雪峰大神的python3教程中的定義:在某個函式(**)執行期間,在不更改該函式的功能下,動態給該函式新增功能的方式,我們稱之為「裝飾器」。從定義中看出,這個裝飾器勢必要在實現中傳入原函式,並在其功能中使原函式功能不受影響。由此我們想到的一種實現裝飾器的方法就是:「實現乙個功能(可是一段**/函式),該功能的實現要傳入乙個函式。」翻譯過來就是通過乙個函式(比如叫「a」函式)實現裝飾器的功能,但是該函式a的入參需要傳入的是乙個函式(比如叫「b」函式)。那麼想象中的裝飾器實現方式是:在python中,「函式也是一種物件」,這句話是理解裝飾器的基礎。因為函式是一種物件,並且物件能被賦值給變數,所以函式就能被賦值給變數。例如:# 這裡的b是乙個函式
defa
(b):
b()pass
要使用裝飾器,python中的方法如下:# 這裡的func是乙個函式,與想象中的b函式一致,log就是上面中的a函式
deflog
(func)
:# *args,**kw泛指函式func的入參
def(
*args,
**kw)
:# __name__是python中的乙個屬性,它能返回對應函式的名稱
('call %s():'
% func.__name__)
return func(
*args,
**kw)
呼叫now()函式:# 給函式上面加乙個@符號,再接實現了裝飾器功能的函式名稱
@log
defnow()
('2015-3-25'
)
>>
> now(
)call now():
2015-3
-25
>>
>
defnow()
:...
print
('2015-3-25').
..>>
> f = now
>>
> f(
)
這裡now函式被賦值給了f變數,呼叫now函式,其實就是進行f的呼叫。平時來看,函式一般都有入參(即函式的區域性變數),而因為變數能代表函式,故函式入參為函式也就好理解了。故對實現了裝飾器的函式,它的入參為函式也就不奇怪了。在python中當乙個函式a就將另乙個函式b作為引數,那麼這個函式a就稱之為高階函式。而上面的函式log將func函式作入參,那麼log就是乙個高階函式。
def
lazy_sum
(*args)
:def
sum():
ax =
0for n in args:
ax = ax + n
return ax
return
sum
函式lazy_sum實現了乙個求和的功能,當我們呼叫lazy_sum時,其返回的不是直接的求和值,而是乙個函式sum,
>>
> f = lazy_sum(1,
3,5,
7,9)
>>
> f
<
locals
>
.sum at 0x101c6ed90
>
這裡f變數其實就是sum函式,所以要求和的值時,呼叫f才可以。
>>
> f(
)25
「當有乙個函式h,它定義了內部函式g,最後返回了函式g,並且在該過程中g還使用了h函式的區域性變數,那麼這種程式python中稱之為閉包」。根據閉包定義,其實它也是一種返回函式,只不過它的內部函式使用了外部函式的區域性變數(入參)。
有了前面的知識儲備,再來看最開始實現了裝飾器功能的函式log:
def
log(func)
:def
(*args,
**kw)
:print
('call %s():'
% func.__name__)
return func(
*args,
**kw)
在python中,當我們使用裝飾器:
@log
defnow()
:print
('2015-3-25'
)now(
)
now()執行過程,實際上相當於執行了語句:
now = log(now)
有時候我們給某個函式動態新增了功能,但又希望我們新增的功能對於我們的需求是可定製的。因此則有必要給裝飾器新增引數變數。python中給裝飾器新增引數的實現是這樣的:
def
log2
(text)
:def
log(func)
:def
(*args,
**kw)
:print
('%s %s():'
%(text, func.__name__)
)return func(
*args,
**kw)
return log
用法則如下:
@log2(
'execute'
)def
now():
print
('2015-3-25'
)
>>
> now(
)execute now():
2015-3
-25
直觀上看,其實就是給log函式外部再加了一層函式。根據前面的函式定義,不難看出log2是乙個返回函式。而now()的執行過程則相當於執行了下面的語句:
now = log2(
'execute'
)(now)
import functools
deflog
(func)
: @functools.wraps(func)
def(
*args,
**kw)
:print
('call %s():'
% func.__name__)
return func(
*args,
**kw)
import functools
deflog2
(text)
:def
log(func)
: @functools.wraps(func)
def(
*args,
**kw)
:print
('%s %s():'
%(text, func.__name__)
)return func(
*args,
**kw)
return log
當然python的裝飾器使用不止這些。這裡只是最基本的理解(若有理解錯的,請各位大佬指正哈)。對裝飾器的理解首先是要知道函式也是物件,其次只要弄清楚一些函式定義就可以了。當然這裡還是得感謝廖雪峰大神的python3教程,正是因為他那清晰透徹的教程,才使我理解裝飾器的概念。 python 裝飾器的基本原理
裝飾器的本質 就是函式,功能是為其他函式新增附加功能 原則 不修改被修飾函式的源 不修改被修飾函式的呼叫方式 import time def cal l start time time.time res 0 for i in l time sleep 0.1 res i stop time time...
mysql的基本原理 Mysql 基本原理
mysql 基本原理 mysql是一種關聯式資料庫管理系統,關聯式資料庫將資料儲存在不同的表中,而不是將所有資料放在乙個大倉庫內,這樣就增加了速度並提高了靈活性 ysql是資料庫登入命令 uroot預設超級使用者登入 p 預設沒密碼 中寫密碼 mysqladmin uroot password 12...
8 2 1 基本原理
乙個舞台動畫物件在包含許多舞台資訊 出現在何處,佔多大面積,處在什麼角度,是否可見 這些資訊分別儲存在動畫物件的屬性中。在 中讀取這些屬性可以了解物件的位置 大小 角度等狀態資訊 修改這些屬性可以改變物件的位置 大小 角度等狀態。如果從資料的角度去理解,動畫就是在固定時間間隔點不斷修改動畫物件某項屬...