網站首頁 編程語言 正文
一、提要
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
相關推薦
- 2022-11-24 Django?ORM?F對象和Q對象查詢_python
- 2022-08-03 在Oracle表中進行關鍵詞搜索的過程_oracle
- 2022-05-21 淺談GO中的Channel以及死鎖的造成_Golang
- 2022-06-12 C語言?詳細解析時間復雜度與空間復雜度_C 語言
- 2022-05-31 Python學習之yaml文件的讀取詳解_python
- 2022-05-28 C語言?超詳細講解庫函數(shù)_C 語言
- 2024-03-19 關于maven打包時,沒有將依賴包打進來的問題
- 2022-04-14 Python中五種列表拷貝的方法_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支