python內建裝飾器 @property
阿新 • • 發佈:2020-12-23
最近看Robotframe中SeleniumLibrary 原始碼,發現原始碼中存在許多@property,因此看下python中內建的裝飾器。
簡言之,python 內建的裝飾器常見為3個 ,分別為@property 、@classmethod和@staticmethod。
property 原始碼分析
檢視property定義 class property(fget=None, fset=None, fdel=None, doc=None) ,說明property是一個類,包含3個可呼叫引數,和一個str的引數。返回為一個 property 屬性。
class property(object): def __init__(self, fget: Optional[Callable[[Any], Any]] = ..., fset: Optional[Callable[[Any, Any], None]] = ..., fdel: Optional[Callable[[Any], None]] = ..., doc: Optional[str] = ...) -> None: ... def getter(self, fget: Callable[[Any], Any]) -> property: ... def setter(self, fset: Callable[[Any, Any], None]) -> property: ... def deleter(self, fdel: Callable[[Any], None]) -> property: ... def __get__(self, obj: Any, type: Optional[type] = ...) -> Any: ... def __set__(self, obj: Any, value: Any) -> None: ... def __delete__(self, obj: Any) -> None: ... def fget(self) -> Any: ... def fset(self, value: Any) -> None: ... def fdel(self) -> None: ...
採用測試程式碼 python 版本為3.5.2
class C: def __init__(self): self._x = None def getx(self): return self._x def setx(self, value): self._x = value def delx(self): del self._x test = C() x = property(test.getx,test.setx,test.delx,"I'm the 'x' property.") test.x = 5 print(test.x) del test.x
通過x = property(test.getx,test.setx,test.delx,"I'm the 'x' property.") 將x變更為類物件test的屬性,可以對其進行 賦值 刪除等操作。
property 作為裝飾器應用
先看下面程式碼
class number(object):
def __init__(self):
self._x = 1000
# @property
def get_x(self):
return self._x
test = number()
print(test.get_x())
在方法未新增裝飾器前,get_x是一個可以修改的類的方法。而新增 @property裝飾器後,get_x 從類的方法變更為類屬性,從而呼叫方式也發生變化。
在之前的原始碼分析中,property可以傳入三個引數,前面的裝飾器只裝飾了一個函式,可以採用以下方式進行裝飾三個函式
class C:
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
test = C()
test.x = 5
print(test.x)
可以看出這與原始碼中的結果是一樣的,實際上 原始碼中的程式碼 屬於 裝飾器的另一種呼叫方法。
小結
property 本身上就是採用類方式實現的裝飾器,若在類內部使用,則將類中定義的方法轉換為類的屬性,且將對類屬性的賦值、刪除操作變得和變數操作一樣,
可以說實現了多型。建議採用@property 裝飾器的呼叫方法。應用方式
- 單一裝飾 直接採用@property 此裝飾器 相當於呼叫fget, 將類中的方法裝換為類屬性
- 進一步裝飾 @x.setter 、 @x.deleter 將類方法變更為屬性,且對屬性進行 賦值和刪除操作。