浅谈python3 构造函数和析构函数

 更新时间:2020年03月12日 13:27:27   作者:jasonLee_lijiaqi  
这篇文章主要介绍了浅谈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', 'a', 'b', 'C', 'Xa'] {'key1': 'test', 'key': 'value'}

只修改a1,但 a2 的成员变量同时也被改变了!

此问题实际场景中其中一个是在使用wxGride时会遇到:

class MyGrid(wx.grid.Grid):
  def __init__(self, parent, col_titles=["a", "b", "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,
                    0,
                    len(rows))
    self.ProcessTableMessage(msg)

class MyFrame(wx.Frame):
  def __init(self, parent, 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, parent, title=""):
    wx.Frame.__init__(self, parent=parent, title=title)
    self.grid1 = MyGrid(self, col_titles=["a", "b", "c"], data=[["1", "2", "3"]])
    self.grid2 = MyGrid(self, col_titles=["a", "b", "c"], data=[["1", "2", "3"]])
    ...

以上这篇浅谈python3 构造函数和析构函数就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Tkinter中复选菜单是否被选中的判断与设置方式

    Tkinter中复选菜单是否被选中的判断与设置方式

    这篇文章主要介绍了Tkinter中复选菜单是否被选中的判断与设置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Python中函数的基本定义与调用及内置函数详解

    Python中函数的基本定义与调用及内置函数详解

    这篇文章主要给大家介绍了关于Python中函数的基本定义与调用及内置函数的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • pyqt5教程QGraphicsScene及QGraphicsView使用基础

    pyqt5教程QGraphicsScene及QGraphicsView使用基础

    这篇文章主要为大家介绍了pyqt5教程中QGraphicsScene及QGraphicsView使用基础,有序要的朋友可以借鉴参考下,希望能够有所帮助
    2021-10-10
  • Python lambda函数使用方法深度总结

    Python lambda函数使用方法深度总结

    在本文中,小编将带大家学习一下Python中的lambda函数,并探讨使用它的优点和局限性。文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-05-05
  • Python将CSV文件转化为HTML文件的操作方法

    Python将CSV文件转化为HTML文件的操作方法

    很多朋友问小编Python如何将CSV文件转化为HTML文件,csv文件读取怎么操作呢?带着这些问题一起通过本文学习吧
    2021-06-06
  • python实现求两个字符串的最长公共子串方法

    python实现求两个字符串的最长公共子串方法

    今天小编就为大家分享一篇python实现求两个字符串的最长公共子串方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 利用selenium爬虫抓取数据的基础教程

    利用selenium爬虫抓取数据的基础教程

    这篇文章主要给大家介绍了关于如何利用selenium爬虫抓取数据的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用selenium具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • Python生成截图选餐GIF动画

    Python生成截图选餐GIF动画

    本篇文章主要介绍了Python生成截图选餐GIF动画,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Python3基础教程之递归函数简单示例

    Python3基础教程之递归函数简单示例

    这篇文章主要给大家介绍了关于Python3基础教程之递归函数简单示例的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python3具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • Python获取网页数据详解流程

    Python获取网页数据详解流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用Python来获取网页的数据,主要应用了Requests库,大家可以在过程中查缺补漏,提升水平
    2021-10-10

最新评论