三個面向物件相關的裝飾器@[email protec
@property
先看例項:
1 from math import pi 2 class Circle: 3 def __init__(self,r): 4 self.r = r 5 @property 6 def perimeter(self): 7 return 2*pi*self.r 8 @property 9 def area(self): 10 return self.r**2*pi 11 12 # c1 = Circle(5) 13 # print(c1.area) # 圓的面積14 # print(c1.perimeter) # 圓的周長
上邊求圓的周長和圓的面積的類中,圓的周長和麵積本來應該是屬性,可是在一般的求解中,我們卻要使用例項.方法名()的形式來求出結果,顯然與真實世界對於屬性的定義有些矛盾。現在可以通過在方法前@property,將此其偽裝成一個屬性,這樣我們可以通過
例項.方法來呼叫,效果與例項.方法名() 是一樣的。
在看下邊這個例項:
class Person: def __init__(self,name): self.__name = name @property def name(self): return self.__name @name.deleter def name(self): del self.__name @name.setter def name(self,new_name): self.__name = new_name
類中的方法名本來是不能用相同名字的,但只要使用@property加在someone之前,並且在再此定義此someone前,@someone.setter,@someone.deleter。這樣在類例項化化後,呼叫物件.someone
呼叫物件.someone=sthing就相當於呼叫@someone.setter下的方法,並且傳進去一個引數sthing。呼叫del.物件.someone相當於呼叫@someone.deleter下的方法。
說到@property就要提到property這個函式 請看例子:
1 class C(object): 2 def __init__(self): 3 self._x = None 4 5 def getx(self): 6 return self._x 7 8 def setx(self, value): 9 self._x = value 10 11 def delx(self): 12 del self._x 13 14 x = property(getx, setx, delx, "I'm the 'x' property.")
以下是 property() 方法的語法:
classproperty([fget[, fset[, fdel[, doc]]]])
- fget -- 獲取屬性值的函式
- fset -- 設定屬性值的函式
- fdel -- 刪除屬性值函式
- doc -- 屬性描述資訊
返回新式類屬性,效果與@property相同。
@classmethod
@classmethod # 把一個方法 變成一個類中的方法,這個方法就直接可以被類呼叫,不需要依託任何物件。
當這個方法的操作只涉及靜態屬性的時候 就應該使用classmethod來裝飾這個方法。
class someone: __sthing = "abc" #定義一個類的私有屬性 @classmethod # 把一個方法 變成一個類中的方法 def change_sthing(cls,new_sthing): # 修改屬性 cls.__sthing = new_sthing
類似於例項方法要傳個self代表例項物件,此類方法在傳參時,要傳一個形參代表當前類,預設cls。
@staticmathod
在完全面向物件的程式中,
如果一個函式 既和物件沒有關係 也和類沒有關係 那麼就用staticmethod將這個函式變成一個靜態方法
class Login: def __init__(self,name,password): self.name = name self.pwd = password def login(self):pass @staticmethod def get_usr_pwd(): # 靜態方法 usr = input('使用者名稱 :') pwd = input('密碼 :') Login(usr,pwd)
靜態方法就是一個寫在類裡的普通函式。
物件可以呼叫類方法和靜態方法
一般情況下 推薦用類名呼叫
類方法 有一個預設引數 cls 代表這個類 cls
靜態方法 沒有預設的引數 就象函式一樣
通過類.靜態方法呼叫時不會例項化。
classC(object): def__init__(self): self._x = Nonedefgetx(self): returnself._xdefsetx(self, value): self._x = valuedefdelx(self): delself._xx = property(getx, setx, delx, "I'm the 'x' property.")