日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

python知識:裝飾器@property到底有啥用途_python

作者:無水先生 ? 更新時間: 2023-02-09 編程語言

一、提要

python的@property是python的一種裝飾器,是用來修飾方法的。

python @property 裝飾器使一個方法可以像屬性一樣被使用。

除此之外,還有幾個使用場景,本文將敘述這些使用技巧。

二、關于屬性的約定

首先看下屬性的分類:

2.1 類綁定屬性

一般類內屬性是指定義成與類同一存儲單元的屬性,可以類訪問。

而當類實例化成對象后,類變量將做為拷貝加入對象,對象所訪問的屬性是一份拷貝。

這份拷貝修改后易變。

驗證代碼

class Stranger(object):
    name = 'class name'                #類綁定屬性
    def __init__(self, gender=None ):
        self.gender = gender           #對象綁定屬性
        self.name = 'new name'         #對象中屬性,與類屬性的同名拷貝
 
stan = Stranger('male')
print(1,stan.gender)
stan.gender = 'famel'
print(2,stan.gender)
print(3 stan.name)
print( 4, Stranger.name)

結果:

1 male
2 famel
3 new name
4 class name

2.2 對象綁定屬性

凡用self定義的屬性,都是對象綁定屬性,

  • 內部調用時都需要加上self.
  • 外部調用時用 instance_name.property_name進行訪問
class Stranger(object):
    def __init__(self, gender=None ):
        self.gender = gender
 
stan = Stranger('roma')
print(stan.gender)
 
stan.gender = 'Paras'
print(stan.gender)

結果:?

roma
Paras?

注意:事實上實例化后的對象,也可以定義屬性,外部也可以調用。?

2.3 私有屬性?

python的私有屬性沒有編譯限定,知識以單下劃線_開頭,標記此屬性是私有的,但是外部也可以自由訪問(私有的程度不夠多)。

另一種是雙下劃線__開頭的屬性,可以轉化成類屬性訪問

  • 單下劃線_開頭:只是告訴別人這是私有屬性,外部依然可以訪問更改
  • 雙下劃線__開頭:外部不可通過instancename.propertyname來訪問或者更改,實際將其轉化為了_classname__propertyname

三、應用@property裝飾器

python的@property是python的一種裝飾器,是用來修飾方法的。python @property 裝飾器使一個方法可以像屬性一樣被使用,而不需要在調用的時候帶上()?接下來我們會了解什么時候需要使用它,并且在什么場景下需要用到它以及如何合理的使用它。

python類中@property裝飾器,相配合的方法有:

  • setter()?
  • get()?
  • set()

相配合。

3.1 將一個屬性轉成方法

將一個屬性轉化為一個方法時,我們最好加上一個@property?裝飾器來解決這個問題。

在方法定義上面加一個@property?裝飾器,可以在不改變原有調用方式的同時,來將一個屬性改為一個方法。

class Goods():
        def __init__(self,unit_price,weight):
            self.unit_price = unit_price
            self.weight = weight
 
        @property
        def price(self):
            return self.unit_price * self.weight 
 
lemons = Goods(7,4)
print(lemons.price)

? ?28????

?上文中,price是方法,現(xiàn)在將方法轉化成屬性調用。注意這個技巧,要知道原類定義中無price這個屬性,這是一個臨時產生的結果。類同于excel表格的“計算項”。

3.2 私有化某些屬性

對于某些屬性,不可直接訪問。這里的“直接”就是“無條件”的意思;而條件的訪問,就需要裝飾器?@property,下例是雙裝飾器@property和@age.setter配合,對_age進行條件隔離的例子:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self._age = age # 這里的成員屬性_age需要與成員方法age()區(qū)分開
        self.jobb = job
 
    # 讀取age
    @property # 實現(xiàn)一個age相關的getter方法
    def age(self):
        return self._age
 
    # 設置age
    @age.setter # 實現(xiàn)一個age相關的setter方法
    def age(self, value):
        if isinstance(value, int):
            self._age = value
        else:
            raise ValueError("'int' type need")
            
 
if __name__ == "__main__":
    # 創(chuàng)建一個“妹子”
    meizi = Stranger()
 
    meizi.age = 18  # 使用時注意是.age,不是._age
    print("年齡:{age}".format(age=meizi.age))

注意事項:

  • 屬性名與方法名一定要區(qū)分開,不然會進入死循環(huán)(self._age,def age())
  • 實例化的對象使用屬性時,不是調用屬性(meizi._age),而是用的方法名(meizi.age)
  • @property其實就是實現(xiàn)了getter功能; @xxx.setter實現(xiàn)的是setter功能;還有一個 @xxx.deleter實現(xiàn)刪除功能
  • 定義方法的時候 @property必須在 @xxx.setter之前,且二者修飾的方法名相同(age())
  • 如果只實現(xiàn)了 @property(而沒有實現(xiàn)@xxx.setter),那么該屬性為 只讀屬性

3.3 關聯(lián)性修改

比如,我們輸入了first_name、last_name可以得出fullname,下面代碼可以實現(xiàn)全名的屬性獲取。而反過來,對全名進行修改后,如何將連帶的first_name、last_name同步進行修改?。

下文中的?@fullname.setter就是解決此類問題的。

class Person():
    def __init__(self, first_name, last_name):
        self.first = first_name
        self.last = last_name
 
    @property
    def fullname(self):
        return self.first + ' ' + self.last
 
    @fullname.setter
    def fullname(self, name):
        first_name, last_name = name.split()
        self.first = first_name
        self.last = last_name
 
    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)
 
 
person = Person('zhang', 'san')
print(person.fullname)
print(person.last)
print(person.first)
 
person.fullname = 'li si'
print(person.fullname)
print(person.last)
print(person.first)

3.4 刪除屬性的deleter方法

setter?方法類似,當我們需要刪除一個屬性時,我們會使用deleter?方法。

你可以像定義setter?方法一樣來定義一個setter?方法,使用相同的方法名,并在方法上添加@{methodname}.deleter?裝飾器 。

class Person():
    def __init__(self, first_name, last_name):
        self.first = first_name
        self.last = last_name
 
    @property
    def fullname(self):
        return self.first + ' ' + self.last
 
    @fullname.setter
    def fullname(self, name):
        first_name, last_name = name.split()
        self.first = first_name
        self.last = last_name
 
    @fullname.deleter
    def fullname(self):
        self.first = None
        self.last = None
 
    def email(self):
        return '{}.{}@email.com'.format(self.first, self.last)
 
 
person = Person('zhang', 'san')
print(person.fullname)
print(person.last)
print(person.first)
 
del person.fullname
 
print(person.last)
print(person.first)

四、property()函數(shù)原理

使用該函數(shù)可以將方法直接變成屬性,與@property類同。

函數(shù)接口:

property(fget=None, fset=None, fdel=None, doc=None)

使用property的代碼示例:

class Stranger(object):
    def __init__(self, gender=None, age=None, job=None):
        self.gender = gender
        self._age = age
        self.jobb = job
 
    # 設置_age
    def set_age(self, age):
        if isinstance(age, int):
            self._age = age
        else:
            raise ValueError("'int' type need")
 
    # 讀取_age
    def get_age(self):
        return self._age
    
    # 使得實例化對象可以利用.age方式來訪問
    age = property(get_age, set_age)
 
 
if __name__ == "__main__":
    # 創(chuàng)建一個“妹子”
    meizi = Stranger()
 
    meizi.age = 18
    print("年齡:{age}".format(age=meizi.age))

# 輸出:
#年齡:18

總結

原文鏈接:https://yamagota.blog.csdn.net/article/details/125402452

欄目分類
最近更新