python的裝飾器是python的特色高階功能之一,言簡意賅得說,其作用是在不改變其原有函式和類的定義的基礎上,給他們增添新的功能。
裝飾器存在的意義是什麼呢?我們知道,在python中函式可以呼叫,類可以繼承,為何要必須保證不改變函式和類的定義,就使得函式有了新的功能呢?其實很好解釋。
提高**的簡潔程度與封裝性。如果你採用新宣告乙個函式,並呼叫原來函式的思路使得原函式功能增加了,但是一方面使用起來看著不簡潔, 另一方面當另乙個程式設計師使用你的**時再使用這樣的思路,那**巢狀無窮無盡,會讓**變得很亂,說不定改錯了**,動了原函式哪個引數,就會出現發現不了的bug。
我們先來看乙個簡單的例子。
def addworld(func):def addfun():
return func() + 'world'
return addfun()
@addworld
def printhello():
return 'hello'
print(printhello)
這段**最後執行出來的結果是helloworld。我們發現,只要在原函式頭上加乙個你定義好了的增添功能的模板,以後凡是加上這個,都會增添乙個功能,這提高了開發效率,也看著更加簡潔。
def addnum(func):def addfun(*args, **kwargs):
ret = func(*args, **kwargs)*2
return ret
return addfun
@addnum
def printsum(a, b):
return (a+b)
i = printsum(7, 7)
print(i)
這是有引數的情況下,裝飾器的使用效果,輸出結果為28。
def addnum1(c):def addnum(func):
def addfun(*args, **kwargs):
ret = func(*args, **kwargs)*2*c
return ret
return addfun
return addnum
@addnum1(5)
def printsum(a, b):
return (a+b)
i = printsum(7, 7)
print(i)
裝飾器本身也是可以傳參的,在這個程式中,傳入了乙個常數5,最後得出的結果是140。
接下來,我們介紹幾個常用的python內建裝飾器。
property
在繫結屬性時,如果我們直接把屬性暴露出去,雖然寫起來很簡單,但是,沒辦法檢查引數,導致可以把成績隨便改。這樣顯然是不行的,那麼在函式中,我們往往如何提高程式的魯棒性呢?
class student(object):def get_score(self):
return self._score
def set_score(self, value):
if not isinstance(value, int):
raise valueerror('score must be an integer!')
if value < 0 or value > 100:
raise valueerror('score must between 0 ~ 100!')
self._score = value
s = student()
s.set_score(60)
value = s.get_score()
print(value)
通過呼叫類中的函式從而進一步操作屬性,這樣雖然安全正確卻未免看著複雜,不貼近人類自然的屬性表現。
class student(object):@property
def score(self):
return self._score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise valueerror('score must be an integer!')
if value < 0 or value > 100:
raise valueerror('score must between 0 ~ 100!')
self._score = value
s = student()
s.score = 80
print(s.score)
而加上乙個@property就可以輕鬆解決這個問題,是不是很奇妙?把乙個getter方法變成屬性,只需要加上@property就可以了,此時,@property本身又建立了另乙個裝飾器@score.setter,負責把乙個setter方法變成屬性賦值,於是,我們就擁有乙個可控的屬性操作。
還可以定義唯讀屬性,只定義getter方法,不定義setter方法就是乙個唯讀屬性。
class student(object):@property
def birth(self):
return self._birth
@birth.setter
def birth(self, value):
self._birth = value
@property
def age(self):
return 2014 - self._birth
上面的birth是可讀寫屬性,而age就是乙個唯讀屬性,因為age可以根據birth和當前時間計算出來。
本文**於
三分鐘搞定python基礎
庫的匯入和新增 在機器學習和人工智慧為主導的工業4.0時代,python猶如一股龍捲風襲捲著一切。python作為一門解釋性的物件導向的語言雖然在運算速度上有不足,但是相比於程式運算速度,程式專案開發速度更為重要,而且在在這個裝備氪金時代,運算速度的缺憾完全可以拿硬體來補,何況python還支援並行...
三分鐘搞定JS繼承
基本思想 通過改變prototype的指向形成例項和原型之間的原型鏈 instancesub subtype.prototype instancesuper supertype.prototype object.prototype null 子物件的原型是父物件的例項subtype.prototyp...
沉默三分鐘
網上見此真情之文,藉以自表 原文 http www.hecaitou.net p 3018 沉默三分鐘是心祭。那麼多年了,國旗終於為平民而降。那麼多天了,全民哀悼終於實現。與此同時,火炬停止傳遞,因為這不是乙個歡慶的時刻。很多年後回顧2008年,我 也許寧可它從日曆中消失。還沒有哪一年和今年一樣,才...