python 裝飾器功能以及函數(shù)參數(shù)使用介紹
更新時間:2012年01月27日 20:50:22 作者:
之前學習編程語言大多也就是學的很淺很淺,基本上也是很少涉及到裝飾器這些的類似的內(nèi)容??偸怯X得是一樣很神奇的東西,舍不得學(嘿嘿)。今天看了一下書籍。發(fā)現(xiàn)道理還是很簡單的
簡單的說:裝飾器主要作用就是對函數(shù)進行一些修飾,它的出現(xiàn)是在引入類方法和靜態(tài)方法的時候為了定義靜態(tài)方法出現(xiàn)的。例如為了把foo()函數(shù)聲明成一個靜態(tài)函數(shù)
class Myclass(object):
def staticfoo():
............
............
staticfoo = staticmethod(staticfoo)
可以用裝飾器的方法實現(xiàn):
class Myclass(object):
@staticmethod
def staticfoo():
.........
.........
這個例子很明顯很容易就可以看懂。
說到這里我們舉一個下面的例子,這個例子里面同時涉及到一個重要內(nèi)容,就是對于python中的函數(shù)的本質(zhì)理解。
代碼:
# -*- coding: utf-8 -*-
from time import ctime
from time import sleep
def ftfunc(func):
def timef():
print "[%s] %s() called" % (ctime(),func.__name__)
return func()
return timef
@ftfunc
def foo():
print 'hello'
if __name__ == '__main__':
foo()
sleep(2)
for i in range(2):
sleep(1)
foo()
運行這段代碼;我們可以看到終端依次會輸出以下內(nèi)容:
@ftfunc
def foo():
print 'hello'
可以轉換成以下的代碼:
def foo():
print 'hello'
foo = ftfunc(foo)
再結合上面原來的代碼我們很快就可以體會到了裝飾器的作用。
但是我在編寫這段代碼的時候,有一個地方打錯了:
這段代碼:
return func()
return timef
被我寫成了:
return func
return timef
于是輸出結果就是不一樣,后來終于發(fā)現(xiàn)了一個重要的概念:"foo"是函數(shù)對象的引用,而"foo()"是函數(shù)對象的調(diào)用。關于對象引用是python的重要的基礎概念,在python中一切都是對象,同時類型是屬于對象,而不是變量。一切的變量只是對象的引用,相當于讓這個變量指向這個對象。“foo”正好可以理解成一個變量,只不過是它指向一個函數(shù)的對象。而“foo()”是函數(shù)對象的調(diào)用,即調(diào)用這個對象,是要執(zhí)行這個函數(shù)的功能的。這里需要慢慢理解品味?;诖耍?
這樣的一段代碼運行結果和剛才是一模一樣的。注意比較與剛才那段代碼的不同之處,更加有利于理解。
# -*- coding: utf-8 -*-
from time import ctime
from time import sleep
def ftfunc(func):
def timef():
print "[%s] %s() called" % (ctime(),func.__name__)
return func
return timef
@ftfunc
def foo():
print 'hello'
if __name__ == '__main__':
foo()()
sleep(2)
for i in range(2):
sleep(1)
foo()()
此代碼運行結果:
復制代碼 代碼如下:
class Myclass(object):
def staticfoo():
............
............
staticfoo = staticmethod(staticfoo)
可以用裝飾器的方法實現(xiàn):
復制代碼 代碼如下:
class Myclass(object):
@staticmethod
def staticfoo():
.........
.........
這個例子很明顯很容易就可以看懂。
說到這里我們舉一個下面的例子,這個例子里面同時涉及到一個重要內(nèi)容,就是對于python中的函數(shù)的本質(zhì)理解。
代碼:
復制代碼 代碼如下:
# -*- coding: utf-8 -*-
from time import ctime
from time import sleep
def ftfunc(func):
def timef():
print "[%s] %s() called" % (ctime(),func.__name__)
return func()
return timef
@ftfunc
def foo():
print 'hello'
if __name__ == '__main__':
foo()
sleep(2)
for i in range(2):
sleep(1)
foo()
運行這段代碼;我們可以看到終端依次會輸出以下內(nèi)容:

其中ftfunc函數(shù)是我們自己自定義的一個函數(shù),這個函數(shù)是以一個函數(shù)作為參數(shù)的函數(shù),這也就滿足了作為一個裝飾器的要求,根據(jù)上面我們對于裝飾器的等價變換規(guī)則,這段代碼
復制代碼 代碼如下:
@ftfunc
def foo():
print 'hello'
可以轉換成以下的代碼:
復制代碼 代碼如下:
def foo():
print 'hello'
foo = ftfunc(foo)
再結合上面原來的代碼我們很快就可以體會到了裝飾器的作用。
但是我在編寫這段代碼的時候,有一個地方打錯了:
這段代碼:
復制代碼 代碼如下:
return func()
return timef
被我寫成了:
復制代碼 代碼如下:
return func
return timef
于是輸出結果就是不一樣,后來終于發(fā)現(xiàn)了一個重要的概念:"foo"是函數(shù)對象的引用,而"foo()"是函數(shù)對象的調(diào)用。關于對象引用是python的重要的基礎概念,在python中一切都是對象,同時類型是屬于對象,而不是變量。一切的變量只是對象的引用,相當于讓這個變量指向這個對象。“foo”正好可以理解成一個變量,只不過是它指向一個函數(shù)的對象。而“foo()”是函數(shù)對象的調(diào)用,即調(diào)用這個對象,是要執(zhí)行這個函數(shù)的功能的。這里需要慢慢理解品味?;诖耍?
這樣的一段代碼運行結果和剛才是一模一樣的。注意比較與剛才那段代碼的不同之處,更加有利于理解。
復制代碼 代碼如下:
# -*- coding: utf-8 -*-
from time import ctime
from time import sleep
def ftfunc(func):
def timef():
print "[%s] %s() called" % (ctime(),func.__name__)
return func
return timef
@ftfunc
def foo():
print 'hello'
if __name__ == '__main__':
foo()()
sleep(2)
for i in range(2):
sleep(1)
foo()()
此代碼運行結果:

其實還可以分別對返回的timef函數(shù)加上括號,看看結果會是怎么樣的??梢愿美斫鈖ython中函數(shù)的概念。
相關文章
Python內(nèi)置方法實現(xiàn)字符串的秘鑰加解密(推薦)
在Python中實現(xiàn)AES算法需要借助的第三方庫Crypto,其在各個操作系統(tǒng)上的安裝方法有些許復雜,所以對于簡單的使用有點殺雞用牛刀的意思。這篇文章主要介紹了利用Python內(nèi)置方法實現(xiàn)字符串的秘鑰加解密,需要的朋友可以參考下2019-12-12
Pandas 缺失數(shù)據(jù)處理的實現(xiàn)
這篇文章主要介紹了Pandas 缺失數(shù)據(jù)處理的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11
tensorflow mnist 數(shù)據(jù)加載實現(xiàn)并畫圖效果
TensorFlow™ 是一個采用數(shù)據(jù)流圖(data flow graphs),用于數(shù)值計算的開源軟件庫。這篇文章給大家介紹tensorflow mnist 數(shù)據(jù)加載實現(xiàn)并畫圖效果,感興趣的朋友一起看看吧2020-02-02

