最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python中@property注解的具體使用

 更新時(shí)間:2025年12月26日 09:10:14   作者:大、男人  
property是 Python 內(nèi)置的裝飾器,用于將類的方法轉(zhuǎn)換為屬性式訪問,本文就來詳細(xì)的介紹一下@property注解的使用,感興趣的可以了解一下

一、@property核心定義

@property 是 Python 內(nèi)置的裝飾器,用于將類的方法轉(zhuǎn)換為屬性式訪問。它允許開發(fā)者將方法以屬性的形式調(diào)用(如 obj.attr 而非 obj.attr()),同時(shí)封裝屬性的讀取(getter)、賦值(setter)、刪除(deleter)邏輯,實(shí)現(xiàn)受控的屬性訪問(如數(shù)據(jù)驗(yàn)證、計(jì)算屬性、隱藏內(nèi)部變量)。

核心價(jià)值:

  • 替代傳統(tǒng)的 get_x()/set_x() 方法,讓屬性訪問更直觀、符合 Python 風(fēng)格;
  • 兼顧封裝性(隱藏內(nèi)部變量)和易用性(屬性式調(diào)用);
  • 支持動(dòng)態(tài)計(jì)算屬性(如根據(jù)其他屬性推導(dǎo)值)、數(shù)據(jù)校驗(yàn)(如限制屬性取值范圍)。

二、基礎(chǔ)用法

1. 只讀屬性(基礎(chǔ) getter)

最核心的用法是將方法轉(zhuǎn)為只讀屬性,適用于「計(jì)算屬性」(值由其他屬性推導(dǎo),無需手動(dòng)賦值)。

示例:圓的面積計(jì)算

class Circle:
    def __init__(self, radius: float):
        self.radius = radius  # 基礎(chǔ)屬性

    @property
    def area(self) -> float:
        """計(jì)算面積(只讀屬性),無需調(diào)用方法,直接訪問"""
        return 3.1415926 * self.radius **2

# 使用:像訪問普通屬性一樣調(diào)用,無需加 ()
c = Circle(5)
print(c.area)  # 輸出:78.539815
# 嘗試賦值會(huì)報(bào)錯(cuò)(只讀屬性)
# c.area = 100  # AttributeError: can't set attribute

2. 可寫屬性(setter 裝飾器)

通過 @屬性名.setter 裝飾器定義賦值邏輯,實(shí)現(xiàn)屬性的可控寫入(如數(shù)據(jù)驗(yàn)證)。

示例:年齡屬性的校驗(yàn)

class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self._age = age  # 下劃線前綴:約定俗成的「私有變量」(Python 無真正私有)

    @property
    def age(self) -> int:
        """getter:讀取年齡"""
        return self._age

    @age.setter
    def age(self, value: int):
        """setter:賦值時(shí)驗(yàn)證數(shù)據(jù)合法性"""
        # 類型校驗(yàn)
        if not isinstance(value, int):
            raise TypeError("年齡必須是整數(shù)")
        # 范圍校驗(yàn)
        if value < 0 or value > 150:
            raise ValueError("年齡必須在 0-150 之間")
        self._age = value

# 使用:賦值時(shí)自動(dòng)觸發(fā) setter 校驗(yàn)
p = Person("Alice", 20)
print(p.age)  # 20(觸發(fā) getter)
p.age = 25    # 合法賦值(觸發(fā) setter)
# p.age = "30"  # 觸發(fā) TypeError
# p.age = 200   # 觸發(fā) ValueError

3. 可刪除屬性(deleter 裝飾器)

通過 @屬性名.deleter 裝飾器定義屬性刪除邏輯,適用于需要清理資源的場(chǎng)景。

示例:刪除年齡屬性

class Person:
    # (繼承上面的 __init__、age getter/setter)
    @age.deleter
    def age(self):
        """deleter:刪除屬性時(shí)執(zhí)行的邏輯"""
        print("刪除年齡屬性...")
        del self._age

# 使用:刪除屬性觸發(fā) deleter
p = Person("Bob", 30)
del p.age  # 輸出:刪除年齡屬性...
# 此時(shí)訪問 p.age 會(huì)報(bào)錯(cuò)(_age 已被刪除)
# print(p.age)  # AttributeError: 'Person' object has no attribute '_age'

三、進(jìn)階用法

1. 與繼承結(jié)合:重寫父類的 property

子類可重寫父類的 @property 及其 setter/deleter,實(shí)現(xiàn)個(gè)性化邏輯。

class Student(Person):
    @property
    def age(self):
        """重寫 getter:添加學(xué)生年齡的額外提示"""
        print(f"學(xué)生 {self.name} 的年齡:")
        return super().age  # 調(diào)用父類的 getter

    @age.setter
    def age(self, value):
        """重寫 setter:添加學(xué)生年齡的特殊校驗(yàn)"""
        if value < 6 or value > 30:
            raise ValueError("學(xué)生年齡應(yīng)在 6-30 之間")
        super(Student, Student).age.fset(self, value)  # 調(diào)用父類的 setter

# 測(cè)試
s = Student("Charlie", 18)
print(s.age)  # 輸出:學(xué)生 Charlie 的年齡:18
s.age = 35    # 觸發(fā) ValueError

2. 緩存昂貴的計(jì)算屬性

對(duì)于計(jì)算耗時(shí)的屬性(如大數(shù)據(jù)處理、網(wǎng)絡(luò)請(qǐng)求),可結(jié)合 functools.lru_cache 緩存結(jié)果,避免重復(fù)計(jì)算。

import functools

class DataProcessor:
    def __init__(self, raw_data: list[int]):
        self.raw_data = raw_data

    @property
    @functools.lru_cache(maxsize=None)  # 緩存方法結(jié)果
    def processed_data(self) -> list[int]:
        """模擬昂貴的計(jì)算:僅首次調(diào)用時(shí)計(jì)算,后續(xù)直接返回緩存"""
        print("執(zhí)行昂貴計(jì)算...")
        return [x * 2 + 1 for x in self.raw_data]

# 測(cè)試
dp = DataProcessor([1, 2, 3, 4])
print(dp.processed_data)  # 輸出:執(zhí)行昂貴計(jì)算... [3, 5, 7, 9]
print(dp.processed_data)  # 直接返回緩存,無打印

3. 手動(dòng)創(chuàng)建 property 對(duì)象(非裝飾器方式)

@property 本質(zhì)是語(yǔ)法糖,底層通過 property() 類實(shí)現(xiàn)??墒謩?dòng)創(chuàng)建 property 對(duì)象,效果與裝飾器一致:

class Person:
    def __init__(self, age: int):
        self._age = age

    # 定義 getter/setter/deleter 方法
    def get_age(self):
        return self._age

    def set_age(self, value):
        if value < 0:
            raise ValueError("年齡不能為負(fù)")
        self._age = value

    def del_age(self):
        del self._age

    # 手動(dòng)創(chuàng)建 property 對(duì)象:property(fget, fset, fdel, doc)
    age = property(get_age, set_age, del_age, "年齡屬性,支持校驗(yàn)")

# 使用方式與裝飾器一致
p = Person(20)
print(p.age)  # 20
p.age = 25    # 合法

四、關(guān)鍵注意事項(xiàng)

1. 命名規(guī)范:避免變量名沖突

  • 內(nèi)部存儲(chǔ)的變量建議用下劃線前綴(如 _age),與 @property 裝飾的方法名(如 age)區(qū)分,避免無限遞歸:
    # 錯(cuò)誤示例:無限遞歸
    class Person:
        def __init__(self, age):
            self.age = age  # 賦值時(shí)觸發(fā) setter,setter 又賦值 self.age → 遞歸
    
        @property
        def age(self):
            return self.age  # 讀取時(shí)觸發(fā) getter,getter 又讀取 self.age → 遞歸
    
    # 正確:內(nèi)部變量用 _age,property 方法用 age
    

2. 只讀屬性的限制

僅定義 @property(無 setter)的屬性是只讀的,嘗試賦值會(huì)拋出 AttributeError,適合純計(jì)算屬性。

五、@propertyvs 傳統(tǒng) getter/setter

特性@property傳統(tǒng) get_x()/set_x()
調(diào)用方式obj.age(屬性式)obj.get_age()(方法式)
封裝性隱藏內(nèi)部變量(如 _age)需手動(dòng)約定命名規(guī)范
數(shù)據(jù)校驗(yàn)賦值時(shí)自動(dòng)觸發(fā) setter 校驗(yàn)需手動(dòng)調(diào)用 set_x() 校驗(yàn)
代碼可讀性更簡(jiǎn)潔、符合 Python 風(fēng)格冗余、不夠直觀
兼容性僅新式類支持(Python 3 默認(rèn))全版本兼容

六、適用場(chǎng)景總結(jié)

場(chǎng)景推薦用法
計(jì)算屬性(如面積、總價(jià))僅定義 @property(只讀)
需要數(shù)據(jù)校驗(yàn)的屬性定義 @property + @屬性名.setter
需要清理資源的屬性額外定義 @屬性名.deleter
封裝內(nèi)部變量,對(duì)外提供統(tǒng)一訪問接口@property 替代手動(dòng) getter/setter
復(fù)用屬性邏輯(多類共用)自定義描述符(而非 @property)

七、總結(jié)

@property 是 Python 面向?qū)ο缶幊讨袑?shí)現(xiàn)屬性封裝的核心工具,它以簡(jiǎn)潔的語(yǔ)法糖封裝了描述符協(xié)議,兼顧了「易用性」(屬性式訪問)和「封裝性」(受控的讀寫邏輯)。無論是實(shí)現(xiàn)計(jì)算屬性、數(shù)據(jù)校驗(yàn),還是隱藏內(nèi)部變量,@property 都是比傳統(tǒng) getter/setter 更優(yōu)雅的選擇,是 Python 開發(fā)者必須掌握的特性之一。

到此這篇關(guān)于python中@property注解的具體使用的文章就介紹到這了,更多相關(guān)python @property注解內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

肥西县| 巴林左旗| 临沧市| 台北县| 舟山市| 诏安县| 松原市| 惠水县| 和田县| 苏尼特右旗| 彭泽县| 浦城县| 高青县| 青川县| 行唐县| 绥滨县| 阿合奇县| 庆安县| 鄂州市| 图木舒克市| 涿州市| 民县| 上高县| 汪清县| 海盐县| 荔波县| 含山县| 石阡县| 平邑县| 黔南| 张掖市| 雷波县| 应用必备| 内乡县| 延吉市| 泸水县| 日喀则市| 开封县| 娄烦县| 建水县| 安仁县|