Python 類(class)2(@property 與 @setter)

Python 類2

前言

考慮到有這幾天更新的內(nèi)容好像容量有點(diǎn)大.如果是跟著一路看過來的同學(xué),可能會(huì)感覺到比較吃力,打算將內(nèi)容講解的更細(xì)致點(diǎn),容量上更少點(diǎn)

前情提要

在這里插入圖片描述

內(nèi)容提要

@property 裝飾的只讀屬性
@setter 裝飾的寫檢驗(yàn)屬性

內(nèi)容詳情

property

將一個(gè)類的方法用@property來裝飾一下,就變成了一個(gè)只讀的屬性
示例:只讀屬性

class MyClass(object):
    '''類的說明文檔'''

    def __init__(self):
        self._name = ""
        self._age = 0
    
    # 定義一個(gè)用裝飾器裝飾的只讀屬性
    @property
    def age(self):
        return 10
mc1 = MyClass()
print(mc1.age)

運(yùn)行效果


在這里插入圖片描述

代碼解析:

def age(self):
    return 10

這個(gè)東西,看上去像一個(gè)方法
但是因?yàn)橛? @property 裝飾 就變成了一個(gè)只讀屬性

 @property
def age(self):
    return 10

因此,在使用的時(shí)候,只需要用方法名(不要加括號(hào))就可以使用

mc1.age

如果嘗試修改這個(gè)屬性:
示例:嘗試修改只讀屬性

class MyClass(object):
    '''類的說明文檔'''

    def __init__(self):
        self._name = ""
        self._age = 0

    @property
    def age(self):
        return 10
mc1 = MyClass()
print(mc1.age)
mc1.age = 100

運(yùn)行效果


在這里插入圖片描述

這里特意用了只讀屬性來解釋這個(gè)用法,就是想要將它的主要功能之一給說明一下.
那還有什么功能呢?
可以對(duì)屬性做一些必要的計(jì)算
比如,我們?cè)O(shè)計(jì)了一個(gè)叫圓的類
屬性有圓心,半徑
這個(gè)時(shí)候,如果我們想要一個(gè)圓的周長(zhǎng)或者面積
如果用原來的方法,就需要再增加一個(gè)圓的周長(zhǎng)屬性或面積屬性.并且,當(dāng)我們改變圓的半徑的時(shí)候,這兩個(gè)屬性還不會(huì)跟著變,要手動(dòng)更新.
而有了這種方法定義的屬性,就可以實(shí)現(xiàn)計(jì)算聯(lián)動(dòng)效果

示例:只讀屬性的計(jì)算聯(lián)動(dòng)效果

class MyCircle(object):
    def __init__(self, radius):
        self.radius = radius

    @property
    def perimeter(self):
        return 2 * 3.14 * self.radius


mc2 = MyCircle(10)
print(mc2.perimeter)
mc2.radius = 20
print(mc2.perimeter)

運(yùn)行效果


在這里插入圖片描述

可以看到,當(dāng)我們改變了圓的半徑后,圓的直徑也跟著發(fā)生了改變.
而這種能力,用普通的屬性就很難實(shí)現(xiàn)

那我們即想實(shí)現(xiàn)這種效果,又想這個(gè)屬性是可寫的怎么辦?能不能辦到?
當(dāng)然可以,這個(gè)時(shí)候,我們就要用到另一個(gè)裝飾器@setter了

@setter

這個(gè)裝飾器的作用就是將只讀屬性,變成可寫屬性.
那么問題來了,即可讀又可寫,那它與普通屬性的意義何在呢?

示例:setter裝飾器的意義

class MyCircle2(object):
    def __init__(self):
        self.__radius = 0

    @property
    def radius(self):
        return self.__radius

    @radius.setter 
    def radius(self, radius):
        if isinstance(radius, int) or isinstance(radius, float):
            self.__radius = radius
        else:
            print("請(qǐng)輸入半徑的正確類型")

mc3 = MyCircle2()
# 正確的半徑
mc3.radius = 10
print(mc3.radius)

# 錯(cuò)誤的半徑值
mc3.radius = "1"
print(mc3.radius)

運(yùn)行效果:


在這里插入圖片描述

代碼解析:
首先我們定義了一個(gè)用裝飾器裝飾的radius屬性

 @property
    def radius(self):
        return self.__radius

至于返回值這么奇怪,我們先不用理會(huì).可以看到,我們就是定義了一個(gè)只讀屬性radius
然后,我們用setter裝飾器將這個(gè)屬性變成可寫的
setter的用法注意點(diǎn):

  • @屬性名.setter
  • 屬性名與@property 定義的屬性名必須一樣
    如果不一樣,在調(diào)用的時(shí)候就會(huì)報(bào)錯(cuò)
    示例:setter裝飾器的屬性名與property的屬性名不一樣
class MyCircle2(object):
    def __init__(self):
        self.__radius = 0

    @property
    def radius(self):
        return self.__radius

    @radius.setter
    def radius2(self, radius):
        if isinstance(radius, int) or isinstance(radius, float):
            self.__radius = radius
        else:
            print("請(qǐng)輸入半徑的正確類型")

mc3 = MyCircle2()
# 正確的半徑
mc3.radius = 10
print(mc3.radius)

# 錯(cuò)誤的半徑值
mc3.radius2 = "1"
print(mc3.radius)

運(yùn)行效果


在這里插入圖片描述

可以看到在調(diào)用時(shí)會(huì)報(bào)錯(cuò)

在正確的示例代碼中setter裝飾器裝飾的屬性代碼如下:

if isinstance(radius, int) or isinstance(radius, float):
    self.__radius = radius
else:
    print("請(qǐng)輸入半徑的正確類型")

可以看到,在我們賦值的時(shí)候,除了直接改變之外,我們還加一個(gè)條件判斷
用來判斷輸入的值是不是數(shù)值型的,
當(dāng)然,你還可以更加嚴(yán)格的判斷值是不是>0的
也就是,用這種方法改寫的可寫屬性,比直接設(shè)置的屬性更有效的地方在于,我們可以對(duì)所賦的值一個(gè)計(jì)算,檢驗(yàn)的效果,即進(jìn)行一個(gè)錯(cuò)誤預(yù)判處理機(jī)制.

總結(jié)

@property 裝飾的只讀屬性

  • 在要轉(zhuǎn)化為屬性的方法前使用
  • 將方法轉(zhuǎn)化為屬性使用邏輯
  • 參數(shù)只能有一個(gè)self
  • 如果只定義@property則屬性將只讀的
  • 如果只定義@property的意義是將該屬性定義成可以與其他屬性聯(lián)動(dòng)效果的屬性.

@setter 裝飾的寫檢驗(yàn)屬性

  • 要用@屬性名.setter
  • 方法名必須與@property定義的屬性名一樣
  • 參數(shù)除了self, 還必須有且只有一個(gè)參數(shù),可以是不定長(zhǎng)參數(shù)
  • 定義@setter 的主要意義在于對(duì)屬性賦值時(shí),可以進(jìn)行一個(gè)額外的處理
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末孵滞,一起剝皮案震驚了整個(gè)濱河市掏父,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谱姓,老刑警劉巖衩侥,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件国旷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡顿乒,警方通過查閱死者的電腦和手機(jī)议街,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來璧榄,“玉大人,你說我怎么就攤上這事吧雹」窃樱” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵雄卷,是天一觀的道長(zhǎng)搓蚪。 經(jīng)常有香客問我,道長(zhǎng)丁鹉,這世上最難降的妖魔是什么妒潭? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮揣钦,結(jié)果婚禮上雳灾,老公的妹妹穿的比我還像新娘。我一直安慰自己冯凹,他們只是感情好谎亩,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般匈庭。 火紅的嫁衣襯著肌膚如雪夫凸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天阱持,我揣著相機(jī)與錄音夭拌,去河邊找鬼。 笑死衷咽,一個(gè)胖子當(dāng)著我的面吹牛鸽扁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兵罢,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼献烦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了卖词?” 一聲冷哼從身側(cè)響起巩那,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎此蜈,沒想到半個(gè)月后即横,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裆赵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年东囚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片战授。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡页藻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出植兰,到底是詐尸還是另有隱情份帐,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布楣导,位于F島的核電站废境,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏筒繁。R本人自食惡果不足惜噩凹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望毡咏。 院中可真熱鬧驮宴,春花似錦、人聲如沸血当。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至落恼,卻和暖如春箩退,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背佳谦。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工戴涝, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钻蔑。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓啥刻,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親咪笑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子可帽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容