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

Python 類2

前言

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

前情提要

在這里插入圖片描述

內(nèi)容提要

@property 裝飾的只讀屬性
@setter 裝飾的寫檢驗屬性

內(nèi)容詳情

property

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

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

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

運行效果


在這里插入圖片描述

代碼解析:

def age(self):
    return 10

這個東西,看上去像一個方法
但是因為有 @property 裝飾 就變成了一個只讀屬性

 @property
def age(self):
    return 10

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

mc1.age

如果嘗試修改這個屬性:
示例:嘗試修改只讀屬性

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

運行效果


在這里插入圖片描述

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

示例:只讀屬性的計算聯(lián)動效果

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)

運行效果


在這里插入圖片描述

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

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

@setter

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

示例: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("請輸入半徑的正確類型")

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

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

運行效果:


在這里插入圖片描述

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

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

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

  • @屬性名.setter
  • 屬性名與@property 定義的屬性名必須一樣
    如果不一樣,在調(diào)用的時候就會報錯
    示例: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("請輸入半徑的正確類型")

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

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

運行效果


在這里插入圖片描述

可以看到在調(diào)用時會報錯

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

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

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

總結(jié)

@property 裝飾的只讀屬性

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

@setter 裝飾的寫檢驗屬性

  • 要用@屬性名.setter
  • 方法名必須與@property定義的屬性名一樣
  • 參數(shù)除了self, 還必須有且只有一個參數(shù),可以是不定長參數(shù)
  • 定義@setter 的主要意義在于對屬性賦值時,可以進行一個額外的處理
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容