天天看點

Python進階之property屬性

概念

一種用起來像是使用的執行個體屬性一樣的特殊屬性,可以對應于某個方法,本質還是方法

class Foo(object):
    def __init__(self):
        self.name="張三"

    @property
    def prop(self):
        print("property屬性")
        return "xxx"
    
    def fun(self):
        print("普通方法")
        return "yyy"


# 建構執行個體對象
foo = Foo()
print(foo.name) # 使用執行個體屬性
foo.fun()  # 使用普通方法
print(foo.prop) # 使用property屬性
                

功能

property屬性内部進行一系列的邏輯計算,最終将計算結果傳回

好處

以下通過三種方式來修改一個商品的價格,對比出property屬性的好處

傳統方式1:在外部直接修改執行個體屬性

class Goods(object):
    def __init__(self):
        self.price=4000

goods = Goods()
goods.price = 2000
goods.price = 200a
                

缺點:

  • 有沒有資格修改
  • 輸入的資料不好驗證

傳統方式2:通過方法來取得執行個體屬性的值和設定執行個體屬性

class Goods(object):
    def __init__(self):
        self.__price=4000  # 私有屬性

    def get_price(self):
        # 身份驗證
        # 其他的業務
        print("get_price")
        return self.__price

    def set_price(self,new_price):
        # 身份驗證
        # 資料驗證
        print("set_price")
        try:
            self.__price=int(new_price)
        except:
            print("修改價格失敗")
            
            
goods=Goods()
goods.set_price(1600)  # 設定執行個體屬性值
print(goods.get_price())  # 取得執行個體屬性值
                

缺點:

  • 方法名可以随意設定
  • 還是需要調用方法

通過property屬性方式來設定執行個體屬性

class Goods(object):
    def __init__(self):
        self.__price=4000  # 私有屬性

    @property
    def price(self):
        # 身份驗證
        # 其他的業務
        print("get_price")
        return self.__price

    @price.setter
    def price(self,new_price):
        # 身份驗證
        # 資料驗證
        print("set_price")
        try:
            self.__price=int(new_price)
        except:
            print("修改價格失敗")
            
            
# 使用property屬性的通路
p_goods = Goods()
print(p_goods.price)  # 擷取property屬性值
p_goods.price=2600 # 設定property屬性值
print(p_goods.price)  # 擷取property屬性值
                

好處:

  • 将一個屬性的操作方法封裝為一個屬性,使用者用起來就和操作普通屬性完全一緻,非常簡單。

定義

1.通過裝飾器的方式來定義

在執行個體方法的基礎上添加@property裝飾器,并且方法僅有一個self參數

  • 擷取屬性
@property
def 方法名(self):
                
  • 設定屬性(不定義setter方法就是一個隻讀屬性)
@property.setter
def 方法名(self, 參數):
                
  • 删除屬性(幾乎不用)
@property.deleter
def 方法名(self):
                

demo:

class Goods(object):
    def __init__(self):
        self.__price=4000 # 執行個體屬性,私有屬性

    @property
    def price(self):
        # 身份驗證
        # 其他的業務
        print("取值: @property")
        return self.__price

    @price.setter
    def price(self,new_price):
        # 身份驗證
        # 資料驗證
        print("修改值: @price.setter")
        try:
            self.__price=int(new_price)
        except:
            print("修改價格失敗")


    @price.deleter
    def price(self):
        print("删除:@price.deleter")

# 通路property屬性的方式
p_goods = Goods()
print(p_goods.price)  # 擷取價格
p_goods.price=600  # 設定價格
print(p_goods.price)  # 擷取價格
del p_goods.price  # 删除價格
print(p_goods.price)  # 擷取價格
                

2.通過裝飾器的方式來定義

  1. 首先需要在類中定義三個對應的方法
  2. 定義類屬性=property(方法名1,方法名2,方法名3,“字元串”)

    第一個參數是方法名: 擷取屬性值

    第二個參數是方法名: 設定屬性值

    第三個參數是方法名: 删除屬性

    第四個參數是字元串: 該屬性的描述資訊,通過類名.屬性名.__doc__調用

demo:

class Goods(object):
    def __init__(self):
        self.__price=4000  # 私有屬性

    def get_price(self):
        # 身份驗證
        # 其他的業務
        print("get_price")
        return self.__price

    def set_price(self,new_price):
        # 身份驗證
        # 資料驗證
        print("set_price")
        try:
            self.__price=int(new_price)
        except:
            print("修改價格失敗")

    def del_price(self):
        print("del_price")

    price=property(get_price,set_price,del_price,"商品價格資訊")


# 使用property屬性的通路
p_goods = Goods()
print(p_goods.price)  # 擷取價格
p_goods.price=1000 # 設定價格
print(p_goods.price)  # 擷取價格
del p_goods.price  # 删除價格
print(p_goods.price)  # 擷取價格
print(Goods.price.__doc__)  # 傳回屬性說明字元串