1. 程式人生 > 程式設計 >淺談python3 建構函式和解構函式

淺談python3 建構函式和解構函式

要點:

1、魔法方法,被__雙下劃線所包圍

在適當的時候自動被呼叫

2、在建立一個物件的時候,一定會呼叫建構函式

3、 del解構函式,在del a物件的時候,並一定會呼叫該解構函式

只有當該物件的引用計數為0時才會呼叫解構函式,回收資源

解構函式被python的垃圾回收器銷燬的時候呼叫。當某一個物件沒有被引用時,垃圾回收器自動回收資源,呼叫解構函式

#coding=utf-8
'''
魔法方法,被__雙下劃線所包圍
在適當的時候自動被呼叫
'''
#構造init、析構del
class Rectangle:
  def __init__(self,x,y):
    self.x = x
    self.y = y
    print('構造')
  '''
  del解構函式,並不是在del a物件的時候就會呼叫該解構函式
  只有當該物件的引用計數為0時才會呼叫解構函式,回收資源
  解構函式被python的垃圾回收器銷燬的時候呼叫。當某一個物件沒有被引用時,垃圾回收器自動回收資源,呼叫解構函式
  '''
  def __del__(self):
    print('析構')
  def getPeri(self):
    return (self.x + self.y)*2
  def getArea(self):
    return self.x * self.y
if __name__ == '__main__':
  rect = Rectangle(3,4)
  # a = rect.getArea()
  # b = rect.getPeri()
  # print(a,b)
  rect1 = rect
  del rect1
  # del rect
  while 1:
    pass

補充知識:Python 類成員變數使用預設值初始化時要注意的一個坑

Python 類成員變數使用預設值初始化時要注意的一個坑

標籤(空格分隔): python2.7 python 3.6

考慮到如下場景:

定義class A,class A 包含成員變數 l 和 d, l為陣列, d 為字典;

在 class A 的建構函式中使用預設引數初始化 A 的成員變數 l 和 d ;

具體程式碼如下:

class A:
  def __init__(self,l=["name"],d={"key1": "test"}):
    self.l = l
    self.d = d

現在,在主邏輯函式中定義生成多個 A 的例項,構造時使用建構函式的預設值:

if __name__ == "__main__":
  a1 = A()
  a2 = A()
  print (id(a1.l),id(a1.d))
  print (id(a2.l),id(a2.d))

輸出的結果如下:

python2.7 
(56305416L,56376040L) 
(56305416L,56376040L)

python3.6 
 2036953558112 
 2036953558112

可以看出,使用預設值初始化的2個 A 的例項中,對應的成員變數 l 和 d 指向了同一個地址

現在假設需要在主邏輯函式中分別操作例項a1 和 a2:

if __name__ == "__main__":
  a1 = A()
  a2 = A()
  # print (id(a1.l),id(a1.d))
  # print (id(a2.l),id(a2.d))

  a1.l.extend(["a","b","C","Xa"])
  a1.d["key"] = "value"

  print ("a1",a1.l,a1.d)
  print ("a2",a2.l,a2.d)

輸出結果會如下:

a1 ['name','a','b','C','Xa'] {'key1': 'test','key': 'value'}
a2 ['name','key': 'value'}

只修改a1,但 a2 的成員變數同時也被改變了!

此問題實際場景中其中一個是在使用wxGride時會遇到:

class MyGrid(wx.grid.Grid):
  def __init__(self,parent,col_titles=["a","c"],data=[["1","2","3"]]):
    wx.grid.Grid__init__(self,parent=parent)
    self.col_titls = col_titles
    self.data = data
    ...

  def AppendData(self,rows=[],clear=Flase):
    self.data.extend(rows)
    msg = wx.grid.GridTableMessage(self,wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED,len(rows))
    self.ProcessTableMessage(msg)

class MyFrame(wx.Frame):
  def __init(self,title=""):
    wx.Frame.__init__(self,parent=parent,title=title)
    self.grid1 = MyGrid(self)
    self.grid2 = MyGrid(self)
    ...

  def onGridAddCallback(rows,force=False):
    if isinstance(rows,list) and len(rows) > 0:
      self.grid1.AppendData(rows,force) 

當更新gird1的內容時,gird2的成員變數 data 也發生了改變,因此導致異常

可選的解決方案: 避免使用預設值初始化指標型別成員變數(list,dict …):

class MyFrame(wx.Frame):
  def __init(self,title=title)
    self.grid1 = MyGrid(self,"3"]])
    self.grid2 = MyGrid(self,"3"]])
    ...

以上這篇淺談python3 建構函式和解構函式就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。