国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - Python黑魔法@property裝飾器的使用技巧解析

Python黑魔法@property裝飾器的使用技巧解析

2020-08-27 12:24mattkang Python

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

@property有什么用呢?表面看來,就是將一個方法用屬性的方式來訪問.
上代碼,代碼最清晰了.

?
1
2
3
4
5
6
7
8
9
10
11
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,當成屬性訪問.
現在問題來了,(不是挖掘機技術哪家強),每次調用c.area,都會計算一次,太浪費cpu了,怎樣才能只計算一次呢?這就是lazy property.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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的機制應該很好理解.
在這里,lazy類有__get__方法,說明是個描述器,第一次執行c.area的時候,因為順序問題,先去c.__dict__中找,沒找到,就去類空間找,在類Circle中,有area()方法,于是就被__get__攔截.
在__get__中,調用實例的area()方法算出結果,并動態給實例添加個同名屬性把結果賦給它,即加到c.__dict__中去.
再次執行c.area的時候,先去c.__dict__找,因為此時已經有了,就不會經過area()方法和__get__了.

注意點
請注意以下代碼場景:

代碼片段1:
Python2.6代碼 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:
Python2.6代碼 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的區別在于

?
1
class Parrot(object):

在python2.6下,分別運行測試
片段1:將會提示一個預期的錯誤信息 AttributeError: can't set attribute
片段2:正確運行

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

BIF:
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功能,在文檔中我們可以查到如下信息:

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__().

同時我們也可以通過以下方法來驗證
Python 2.6代碼 

?
1
2
3
4
5
class A:
  pass
 
>>type(A)
<type 'classobj'>

Python 2.6代碼 

?
1
2
3
4
5
class A(object):
  pass
 
>>type(A)
<type 'type'>

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

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

最后的代碼將如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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沒有該功能。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 日本精品视频在线观看 | 国产四区视频 | 国产黄色片免费观看 | 日本一区二区中文字幕 | 久久奸| 手机在线观看 | 精品免费久久久久 | 欧美激情精品久久久久久变态 | 欧美日韩欧美日韩 | 狠狠se | 亚洲精品久久一区二区三区 | 蜜桃臀一区二区三区 | 国产精品久久久久久久久久久久久 | 日本精品久久 | 午夜资源| 成人片网址| 视频一区二区国产 | av久久| 亚洲一区二区久久 | 欧美精品成人一区二区三区四区 | 日本一区二区三区免费观看 | 日韩激情一区 | 欧美在线高清 | av一区二区三区免费观看 | 亚洲日韩中文字幕在线播放 | 日韩在线视频观看 | 亚洲视频第一页 | 超碰8| 日本中文字幕在线播放 | 日韩激情一区二区三区 | 亚洲精品久久久一区二区三区 | 久久人人爽人人爽人人片亚洲 | 日韩一区免费在线观看 | 亚洲欧美网址 | 少妇一级淫免费放 | 精品久久久久久久久久久久久久 | 青青草久| 国产精品久久影院 | 国产精品久久久久久久9999 | 精品久久久久久久久久久久 | 亚洲免费观看 |