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


Posted in Python onMarch 12, 2020

要点:

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 构造函数和析构函数就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python编程-将Python程序转化为可执行程序[整理]
Apr 09 Python
Python 文件操作技巧(File operation) 实例代码分析
Aug 11 Python
在Linux系统上安装Python的Scrapy框架的教程
Jun 11 Python
Python模块搜索路径代码详解
Jan 29 Python
python web基础之加载静态文件实例
Mar 20 Python
python实现textrank关键词提取
Jun 22 Python
Python判断以什么结尾以什么开头的实例
Oct 27 Python
详解Python对JSON中的特殊类型进行Encoder
Jul 15 Python
Python读取excel文件中带公式的值的实现
Apr 17 Python
Python数据正态性检验实现过程
Apr 18 Python
基于Python测试程序是否有错误
May 16 Python
利用Python实现Excel的文件间的数据匹配功能
Jun 16 Python
Python基于yield遍历多个可迭代对象
Mar 12 #Python
Python通过4种方式实现进程数据通信
Mar 12 #Python
Python多进程编程multiprocessing代码实例
Mar 12 #Python
Python多线程多进程实例对比解析
Mar 12 #Python
Python线程协作threading.Condition实现过程解析
Mar 12 #Python
Python 实现网课实时监控自动签到、打卡功能
Mar 12 #Python
Python基于read(size)方法读取超大文件
Mar 12 #Python
You might like
PHP学习笔记之数组篇
2011/06/28 PHP
大家在抢红包,程序员在研究红包算法
2015/08/31 PHP
CI框架简单邮件发送类实例
2016/05/18 PHP
PHP图像识别技术原理与实现
2016/10/27 PHP
JS学习之一个简易的日历控件
2010/03/24 Javascript
AJAX使用了UpdatePanel后无法使用alert弹出脚本
2010/04/02 Javascript
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
ASP.NET jQuery 实例8 (动态添加内容到DropDownList)
2012/02/03 Javascript
javascript中一些util方法汇总
2015/06/10 Javascript
javascript实现超炫的向上滑行菜单实例
2015/08/03 Javascript
分享jQuery插件的学习笔记
2016/01/14 Javascript
Node.js Express 框架 POST方法详解
2017/01/23 Javascript
Bootstrap页面标题Page Header的实现方法
2017/03/22 Javascript
解决OneThink中无法异步提交kindeditor文本框中修改后的内容方法
2017/05/05 Javascript
强大的JavaScript响应式图表Chartist.js的使用
2017/09/13 Javascript
Javasript设计模式之链式调用详解
2018/04/26 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
[01:03:09]完美世界DOTA2联赛PWL S2 Forest vs SZ 第二场 11.25
2020/11/26 DOTA
数据挖掘之Apriori算法详解和Python实现代码分享
2014/11/07 Python
python检测远程端口是否打开的方法
2015/03/14 Python
详谈Pandas中iloc和loc以及ix的区别
2018/06/08 Python
PyQt5实现五子棋游戏(人机对弈)
2020/03/24 Python
NumPy 基本切片和索引的具体使用方法
2019/04/24 Python
Python一键安装全部依赖包的方法
2019/08/12 Python
Django后端按照日期查询的方法教程
2021/02/28 Python
css3加js做一个简单的3D行星运转效果实例代码
2017/01/18 HTML / CSS
武汉某公司的C#笔试题面试题
2015/12/25 面试题
广告学专业自荐信范文
2014/02/24 职场文书
学生吸烟检讨书
2014/09/14 职场文书
班子群众路线教育实践个人对照检查材料思想汇报
2014/09/30 职场文书
如何撰写促销方案?
2019/07/05 职场文书
Axios取消重复请求的方法实例详解
2021/06/15 Javascript
SQL Server2019数据库备份与还原脚本,数据库可批量备份
2021/11/20 SQL Server
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python
css3 选择器
2022/05/11 HTML / CSS
基于Python实现西西成语接龙小助手
2022/08/05 Golang