@property有什麼用呢?表面看來,就是將一個方法用屬性的方式來訪問.
上代碼,代碼最清晰了
class Circle(object): def __init__(self, radius): self.radius = radius @property def area(self): return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.area
可以看到,area
現在問題來了,(不是挖掘機技術哪家強),每次調用c.area,都會計算一次,太浪費cpu了,怎麼樣才能只計算一次呢?這就是lazy property.
class lazy(object): def __init__(self, func): self.func = func def __get__(self, instance, cls): val = self.func(instance) setattr(instance, self.func.__name__, val) return val class Circle(object): def __init__(self, radius): self.radius = radius @lazy def area(self): print 'evalute' return 3.14 * self.radius ** 2 c = Circle(4) print c.radius print c.area print c.area print c.area
在這裡,lazy類別有__get__方法,說明是個描述器,第一次執行c.area的時候,因為順序問題,先去c.__dict__中找,沒找到,就去類空間找,在類別Circle中,有area()方法,於是就被__get__攔截.
在__get__中,調用實例的area()方法算出結果,並動態給實例添加個同名屬性把結果賦給它,即加到c.__dict__中去.
注意點
Python2.6程式碼
class Parrot(object): def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage if __name__ == "__main__": # instance p = Parrot() # similarly invoke "getter" via @property print p.voltage # update, similarly invoke "setter" p.voltage = 12
class Parrot: def __init__(self): self._voltage = 100000 @property def voltage(self): """Get the current voltage.""" return self._voltage if __name__ == "__main__": # instance p = Parrot() # similarly invoke "getter" via @property print p.voltage # update, similarly invoke "setter" p.voltage = 12在python2.6下,分別運行測試
片段1:將會提示一個預期的錯誤訊息AttributeError: can't set attribute
片段2:正確運行
提供一個ready-only property,以上程式碼沒有提供對應的@voltage.setter,按理說片段2程式碼將提示執行錯誤,在python2.6文件中,我們可以找到以下資訊:
property([fget [, fset[, fdel[, doc]]]])
Return a property attribute for new-style classes (classes that derive from object).原來在python2.6下,內建類型object 並不是預設的基類,如果在定義類別時,沒有明確說明的話(程式碼片段2),我們定義的Parrot(程式碼片段2)將不會繼承object
而object類別正好提供了我們需要的@property功能,在文件中我們可以查到以下資訊:
Any class which inherits from object. This includes all built-in types like list and dict. Only new-style classes can __use's newer, versatile classs can __crance,與 __getattribute__().
同時我們也可以透過以下方法驗證
Python 2.6程式碼
class Parrot(object):
class A: pass >>type(A) <type 'classobj'>另外,@property是在2.6、3.0
另外,@property是在2.6、3.0
另外,@property是在2.6、3.0另外,@property是在2.6、3.0
另外,@property是在2.6、3.0新增的,2.5沒有該功能。 🎜🎜更多Python黑魔法@property裝飾器的使用技巧解析相關文章請關注PHP中文網! 🎜