内射老阿姨1区2区3区4区_久久精品人人做人人爽电影蜜月_久久国产精品亚洲77777_99精品又大又爽又粗少妇毛片

Python黑魔法之property裝飾器的示例

這篇文章主要介紹了Python黑魔法之property裝飾器的示例,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

專業(yè)成都網(wǎng)站建設(shè)公司,做排名好的好網(wǎng)站,排在同行前面,為您帶來客戶和效益!創(chuàng)新互聯(lián)為您提供成都網(wǎng)站建設(shè),五站合一網(wǎng)站設(shè)計制作,服務(wù)好的網(wǎng)站設(shè)計公司,成都做網(wǎng)站、成都網(wǎng)站設(shè)計負(fù)責(zé)任的成都網(wǎng)站制作公司!

@property裝飾器能把一個方法變成屬性一樣來調(diào)用,下面我們就一起來看看Python黑魔法@property裝飾器的使用技巧解析

@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雖然是定義成一個方法的形式,但是加上@property后,可以直接c.area,當(dāng)成屬性訪問.

現(xiàn)在問題來了,每次調(diào)用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

可以看到,'evalute'只輸出了一次,對@lazy的機(jī)制應(yīng)該很好理解.

在這里,lazy類有__get__方法,說明是個描述器,第一次執(zhí)行c.area的時候,因為順序問題,先去c.__dict__中找,沒找到,就去類空間找,在類Circle中,有area()方法,于是就被__get__攔截.

在__get__中,調(diào)用實例的area()方法算出結(jié)果,并動態(tài)給實例添加個同名屬性把結(jié)果賦給它,即加到c.__dict__中去.

再次執(zhí)行c.area的時候,先去c.__dict__找,因為此時已經(jīng)有了,就不會經(jīng)過area()方法和__get__了.

注意點

請注意以下代碼場景:

代碼片段1:  

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

代碼片段2

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

代碼1、2的區(qū)別在于 

class Parrot(object): 

在python2下,分別運行測試 

片段1:將會提示一個預(yù)期的錯誤信息 AttributeError: can't set attribute 

片段2:正確運行

參考python2文檔,@property將提供一個ready-only property,以上代碼沒有提供對應(yīng)的@voltage.setter,按理說片段2代碼將提示運行錯誤,在python2文檔中,我們可以找到以下信息:

BIF: 

property([fget[, fset[, fdel[, doc]]]]) 

Return a property attribute for new-style classes (classes that derive from object). 

原來在python2下,內(nèi)置類型 object 并不是默認(rèn)的基類,如果在定義類時,沒有明確說明的話(代碼片段2),我們定義的Parrot(代碼片段2)將不會繼承object

而object類正好提供了我們需要的@property功能,在文檔中我們可以查到如下信息:

new-style class 

Any class which inherits from object. This includes all built-in types like list and dict. Only new-style classes can use Python's newer, versatile features like __slots__, descriptors, properties, and __getattribute__().

同時我們也可以通過以下方法來驗證 

class A: 
  pass 
>>type(A) 
<type 'classobj'>
class A(object): 
  pass 
>>type(A) 
<type 'type'>

從返回的<type 'classobj'>,<type 'type'>可以看出<type 'type'>是我們需要的object類型(python 3.0 將object類作為默認(rèn)基類,所以都將返回<type 'type'>)

為了考慮代碼的python 版本過渡期的兼容性問題,我覺得應(yīng)該定義class文件的時候,都應(yīng)該顯式定義object,做為一個好習(xí)慣

最后的代碼將如下

class Parrot(object): 
  def __init__(self): 
    self._voltage = 100000 
  @property 
  def voltage(self): 
    """Get the current voltage.""" 
    return self._voltage 
  @voltage.setter 
  def voltage(self, new_value): 
    self._voltage = new_value 
  
if __name__ == "__main__": 
  # instance 
  p = Parrot() 
  # similarly invoke "getter" via @property 
  print p.voltage 
  # update, similarly invoke "setter" 
  p.voltage = 12

另外,@property是在2.6、3.0新增的,2.5沒有該功能。 

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享Python黑魔法之property裝飾器的示例內(nèi)容對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián),詳細(xì)的解決方法等著你來學(xué)習(xí)!

當(dāng)前題目:Python黑魔法之property裝飾器的示例
URL鏈接:http://www.rwnh.cn/article8/jisdop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、手機(jī)網(wǎng)站建設(shè)、企業(yè)建站、App設(shè)計網(wǎng)站制作、網(wǎng)站排名

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)
定陶县| 花莲市| 克山县| 富锦市| 平江县| 多伦县| 泾阳县| 华亭县| 延安市| 股票| 荃湾区| 长岭县| 鄂温| 高碑店市| 绥化市| 昔阳县| 陵水| 肥乡县| 桐柏县| 平舆县| 桦川县| 德清县| 阿巴嘎旗| 林口县| 全椒县| 潜江市| 资讯| 石家庄市| 舞钢市| 巢湖市| 开阳县| 雷山县| 黔西| 光山县| 丰原市| 广汉市| 佛坪县| 田林县| 丽水市| 静海县| 望奎县|