python知識:裝飾器@property到底有啥用途
一、提要
python的@property是python的一種裝飾器,是用來修飾方法的。
python @property 裝飾器使一個方法可以像屬性一樣被使用。
除此之外,還有幾個使用場景,本文將敘述這些使用技巧。
二、關(guān)于屬性的約定
首先看下屬性的分類:
2.1 類綁定屬性
一般類內(nèi)屬性是指定義成與類同一存儲單元的屬性,可以類訪問。
而當(dāng)類實例化成對象后,類變量將做為拷貝加入對象,對象所訪問的屬性是一份拷貝。
這份拷貝修改后易變。
驗證代碼
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)
結(jié)果:
1 male
2 famel
3 new name
4 class name
2.2 對象綁定屬性
凡用self定義的屬性,都是對象綁定屬性,
- 內(nèi)部調(diào)用時都需要加上self.
- 外部調(diào)用時用 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)
結(jié)果:
roma
Paras
注意:事實上實例化后的對象,也可以定義屬性,外部也可以調(diào)用。
2.3 私有屬性
python的私有屬性沒有編譯限定,知識以單下劃線_開頭,標(biāo)記此屬性是私有的,但是外部也可以自由訪問(私有的程度不夠多)。
另一種是雙下劃線__開頭的屬性,可以轉(zhuǎn)化成類屬性訪問
- 單下劃線_開頭:只是告訴別人這是私有屬性,外部依然可以訪問更改
- 雙下劃線__開頭:外部不可通過instancename.propertyname來訪問或者更改,實際將其轉(zhuǎn)化為了_classname__propertyname
三、應(yīng)用@property裝飾器
python的@property是python的一種裝飾器,是用來修飾方法的。python @property 裝飾器使一個方法可以像屬性一樣被使用,而不需要在調(diào)用的時候帶上()
接下來我們會了解什么時候需要使用它,并且在什么場景下需要用到它以及如何合理的使用它。
python類中@property裝飾器,相配合的方法有:
setter()
get()
set()
相配合。
3.1 將一個屬性轉(zhuǎn)成方法
將一個屬性轉(zhuǎn)化為一個方法時,我們最好加上一個@property
裝飾器來解決這個問題。
在方法定義上面加一個@property
裝飾器,可以在不改變原有調(diào)用方式的同時,來將一個屬性改為一個方法。
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)在將方法轉(zhuǎn)化成屬性調(diào)用。注意這個技巧,要知道原類定義中無price這個屬性,這是一個臨時產(chǎn)生的結(jié)果。類同于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相關(guān)的getter方法 def age(self): return self._age # 設(shè)置age @age.setter # 實現(xiàn)一個age相關(guān)的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())
- 實例化的對象使用屬性時,不是調(diào)用屬性(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 關(guān)聯(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
方法類似,當(dāng)我們需要刪除一個屬性時,我們會使用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 # 設(shè)置_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
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- Python?property裝飾器使用案例介紹
- Python深入分析@property裝飾器的應(yīng)用
- python中的property及屬性與特性之間的優(yōu)先權(quán)
- python 中的@property的用法詳解
- python中@Property屬性使用方法
- Python中property屬性的用處詳解
- python?@property?裝飾器使用方法
- Python裝飾器中@property使用詳解
- Python中關(guān)于property使用的小技巧
- Python的@property的使用
- 詳解Python裝飾器之@property
- Python中通過property設(shè)置類屬性的訪問
相關(guān)文章
selenium+python實現(xiàn)基本自動化測試的示例代碼
這篇文章主要介紹了selenium+python實現(xiàn)基本自動化測試的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01Python Django項目和應(yīng)用的創(chuàng)建詳解
這篇文章主要為大家介紹了Python Django項目和應(yīng)用的創(chuàng)建,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-11-11詳解Pycharm出現(xiàn)out of memory的終極解決方法
這篇文章主要介紹了詳解Pycharm出現(xiàn)out of memory的終極解決方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Python基于socket實現(xiàn)簡單的即時通訊功能示例
這篇文章主要介紹了Python基于socket實現(xiàn)簡單的即時通訊功能,涉及Python基于socket模塊實現(xiàn)tcp通信客戶端與服務(wù)器端相關(guān)操作技巧,需要的朋友可以參考下2018-01-01Python Pickling 和 Unpickling 的區(qū)別
Python中的Pickling和Unpickling是與數(shù)據(jù)序列化和反序列化相關(guān)的重要概念,本文主要介紹了Python Pickling和Unpickling的區(qū)別,具有一定的參考價值,感興趣的可以了解一下2023-11-11