python的@property是python的一種裝飾器,是用來修飾方法的。python @property 裝飾器使一個方法可以像屬性一樣被使用。除此之外,還有幾個使用場景,本文將敘述這些使用技巧。
首先看下屬性的分類:
一般類內屬性是指定義成與類同一存儲單元的屬性,可以類訪問。而當類實例化成對象後,類變量將做為拷貝加入對象,對象所訪問的屬性是一份拷貝。這份拷貝修改後易變。
驗證代碼
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
凡用self定義的屬性,都是對象綁定屬性,
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
注意:事實上實例化後的對象,也可以定義屬性,外部也可以調用。
python的私有屬性沒有編譯限定,知識以單下劃線_開頭,標記此屬性是私有的,但是外部也可以自由訪問(私有的程度不夠多)。另一種是雙下劃線__開頭的屬性,可以轉化成類屬性訪問
python的@property是python的一種裝飾器,是用來修飾方法的。python @property 裝飾器使一個方法可以像屬性一樣被使用,而不需要在調用的時候帶上()
接下來我們會了解什麼時候需要使用它,並且在什麼場景下需要用到它以及如何合理的使用它。
python類中@property裝飾器,相配合的方法有:
相配合。
將一個屬性轉化為一個方法時,我們最好加上一個@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是方法,現在將方法轉化成屬性調用。注意這個技巧,要知道原類定義中無price這個屬性,這是一個臨時產生的結果。類同於excel表格的“計算項”。
對於某些屬性,不可直接訪問。這裡的“直接”就是“無條件”的意思;而條件的訪問,就需要裝飾器 @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()區分開
self.jobb = job
# 讀取age
@property # 實現一個age相關的getter方法
def age(self):
return self._age
# 設置age
@age.setter # 實現一個age相關的setter方法
def age(self, value):
if isinstance(value, int):
self._age = value
else:
raise ValueError("'int' type need")
if __name__ == "__main__":
# 創建一個“妹子”
meizi = Stranger()
meizi.age = 18 # 使用時注意是.age,不是._age
print("年齡:{age}".format(age=meizi.age))
注意事項:
比如,我們輸入了first_name、last_name可以得出fullname,下面代碼可以實現全名的屬性獲取。而反過來,對全名進行修改後,如何將連帶的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)
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類同。
使用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__":
# 創建一個“妹子”
meizi = Stranger()
meizi.age = 18
print("年齡:{age}".format(age=meizi.age))
# 輸出:
#年齡:18