1. 程式人生 > >Python 中 property() 函式及 @property 裝飾器的使用

Python 中 property() 函式及 @property 裝飾器的使用

Python 中 property() 函式及 @property 裝飾器的使用


文章目錄


0. 參考資料


1. property 應用場景

  • 在獲取、設定和刪除物件屬性的時候,需要額外做一些工作。比如在遊戲程式設計中,設定敵人死亡之後需要播放死亡動畫。
  • 需要限制物件屬性的設定和獲取。比如使用者年齡為只讀,或者在設定使用者年齡的時候有範圍限制。
  • 這時就可以使用 property 工具,它把方法包裝成屬性,讓方法可以以屬性的形式被訪問和呼叫

2. property() 函式

  • 語法:
    property(fget=None, fset=None, fdel=None, doc=None) -> property attribute
  • 說明:
    • fget獲取屬性值的方法
    • fset設定屬性值的方法
    • fdel刪除屬性值的方法
    • doc屬性描述資訊。如果省略,會把 fget 方法的 docstring 拿來用(如果有的話)
  • 示例程式碼:
class Student:
    def __init__(self):
        self._age = None

    def get_age(self):
        print('獲取屬性時執行的程式碼')
        return self._age

    def
set_age(self, age): print('設定屬性時執行的程式碼') self._age = age def del_age(self): print('刪除屬性時執行的程式碼') del self._age age = property(get_age, set_age, del_age, '學生年齡') student = Student() # 注意要用 類名.屬性.__doc__ 的形式檢視屬性的文件字串 print('檢視屬性的文件字串:' + Student.age.__doc__) """ 檢視屬性的文件字串:學生年齡 """ # 設定屬性 student.age = 18 """ 設定屬性時執行的程式碼 """ # 獲取屬性 print('學生年齡為:' + str(student.age)) """ 獲取屬性時執行的程式碼 學生年齡為:18 """ # 刪除屬性 del student.age """ 刪除屬性時執行的程式碼 """

3. @property 裝飾器

@property 語法糖提供了比 property() 函式更簡潔直觀的寫法。

  • @property 裝飾的方法是獲取屬性值的方法,被裝飾方法的名字會被用做 屬性名
  • @屬性名.setter 裝飾的方法是設定屬性值的方法
  • @屬性名.deleter 裝飾的方法是刪除屬性值的方法

以下示例程式碼與使用 property() 函式版本的程式碼等價:

class Student:
    def __init__(self):
        self._age = None

    @property
    def age(self):
        print('獲取屬性時執行的程式碼')
        return self._age

    @age.setter
    def age(self, age):
        print('設定屬性時執行的程式碼')
        self._age = age

    @age.deleter
    def age(self):
        print('刪除屬性時執行的程式碼')
        del self._age


student = Student()

# 設定屬性
student.age = 18
"""
設定屬性時執行的程式碼
"""

# 獲取屬性
print('學生年齡為:' + str(student.age))
"""
獲取屬性時執行的程式碼
學生年齡為:18
"""

# 刪除屬性
del student.age
"""
刪除屬性時執行的程式碼
"""


4. 注意事項

  • 可以省略設定屬性值的方法,此時該屬性變成只讀屬性。如果此時仍然設定屬性,會丟擲異常 AttributeError: can't set attribute
  • 如果報錯 RecursionError: maximum recursion depth exceeded while calling a Python object,很可能是物件屬性名和 @property 裝飾的方法名重名了,一般會在物件屬性名前加一個下劃線 _ 避免重名,並且表明這是一個受保護的屬性。

完成於 20181113