1. 程式人生 > 其它 >Python property()

Python property()

目錄

一、問題

管理物件的屬性。


二、解決方案

定義為property

例項:增加對屬性的型別檢查。

class Person:
    def __init__(self, first_name):
        self._first_name = first_name

    # Getter函式
    @property
    def first_name(self):
        return self._first_name

    # Setter函式
    @first_name.setter
    def first_name(self, value):
        if not isinstance(value, str):
            raise TypeError('不是字串。')
        self._first_name = value

    # Deleter函式
    @first_name.deleter
    def first_name(self):
        raise AttributeError('不能刪除。')

a = Person('ke')
print(a.first_name)

輸出:

ke

上述三個相關聯的方法,名字必須一樣。

第一個方法是Getter函式,使first_name成為一個屬性。

其他兩個方法給first_name屬性新增SetterDeleter函式。只有first_name屬性被建立後,後面的裝飾器@first_name.setter@first_name.deleter才能被定義。

訪問property時會自動觸發gettersetterdeleter方法。

a = Person('ke')
print(a.first_name)

a.first_name = 42

del a.first_name

輸出:

ke

TypeError: 不是字串。
    
AttributeError: 不能刪除。

GetterSetter函式中,是對_first_name屬性進行操作,這是實際資料儲存的地方。



三、討論

property()具有fgetfsetfdel屬性。

print(Person.first_name.fget)
print(Person.first_name.fset)
print(Person.first_name.fdel)

輸出:

<function Person.first_name at 0x0000024E96FA5318>
<function Person.first_name at 0x0000024E99717A68>
<function Person.first_name at 0x0000024E99717AF8>

通常不會直接呼叫fgetfset,會在訪問property時自動觸發。



使用property,將所有訪問介面統一起來,對方法的訪問也是通過屬性訪問。

import math
class Circle:
    def __init__(self, radius):
        self.radius = radius

    @property
    def area(self):
        return math.pi * self.radius ** 2

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

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

c = Circle(4)
print(c.radius)
print(c.area)
print(c.perimeter)

輸出:

4
50.26548245743669
25.132741228718345

這裡對半徑、直徑、周長、面積的訪問都是通過對屬性的訪問。