浅谈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修改字典内key对应值的方法
Jul 11 Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 Python
python机器学习实战之K均值聚类
Dec 20 Python
对Tensorflow中权值和feature map的可视化详解
Jun 14 Python
Python多进程与服务器并发原理及用法实例分析
Aug 21 Python
解决python Markdown模块乱码的问题
Feb 14 Python
python 求某条线上特定x值或y值的点坐标方法
Jul 09 Python
Python reshape的用法及多个二维数组合并为三维数组的实例
Feb 07 Python
Python守护进程实现过程详解
Feb 10 Python
基于Python实现简单学生管理系统
Jul 24 Python
Python如何读取、写入JSON数据
Jul 28 Python
Python导入父文件夹中模块并读取当前文件夹内的资源
Nov 19 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
全国FM电台频率大全 - 15 山东省
2020/03/11 无线电
PHP使用DirectoryIterator显示下拉文件列表的方法
2015/03/13 PHP
PHP计算数组中值的和与乘积的方法(array_sum与array_product函数)
2016/04/01 PHP
Laravel框架模板加载,分配变量及简单路由功能示例
2018/06/11 PHP
JavaScript Konami Code 实现代码
2009/07/29 Javascript
jQuery队列控制方法详解queue()/dequeue()/clearQueue()
2010/12/02 Javascript
判断对象是否Window的实现代码
2012/01/10 Javascript
jQuery事件绑定.on()简要概述及应用
2013/02/07 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
Javascript中浏览器窗口的基本操作总结
2016/08/18 Javascript
Vue组件开发初探
2017/02/14 Javascript
vue组件中点击按钮后修改输入框的状态实例代码
2017/04/14 Javascript
jQuery遍历节点方法汇总(推荐)
2017/05/13 jQuery
Node.js微信 access_token ( jsapi_ticket ) 存取与刷新的示例
2017/09/30 Javascript
javascript实现电脑和手机版样式切换
2017/11/10 Javascript
Vue在chrome44偶现点击子元素事件无法冒泡的解决方法
2019/12/15 Javascript
原生js实现的金山打字小游戏(实例代码详解)
2020/03/16 Javascript
nuxt静态部署打包相对路径操作
2020/11/06 Javascript
[00:30]塑造者的传承礼包-戴泽“暗影之焰”套装展示视频
2014/04/04 DOTA
详解python单例模式与metaclass
2016/01/15 Python
Python requests发送post请求的一些疑点
2018/05/20 Python
对python For 循环的三种遍历方式解析
2019/02/01 Python
python使用多线程+socket实现端口扫描
2020/05/28 Python
Python实现Keras搭建神经网络训练分类模型教程
2020/06/12 Python
美国在线咖啡、茶和餐厅供应商:LollicupStore
2018/05/04 全球购物
澳大利亚珠宝商:Shiels
2019/10/06 全球购物
理工大学毕业生自荐信
2013/11/01 职场文书
英语专业应届生求职信范文
2013/11/15 职场文书
护士毕业实习感言
2014/03/05 职场文书
个人银行贷款担保书
2014/04/01 职场文书
清明节网上祭英烈活动总结
2014/04/30 职场文书
党员个人剖析材料(四风问题)
2014/10/07 职场文书
领导班子整改方案和个人整改措施
2014/10/25 职场文书
2014年保育员个人工作总结
2014/12/02 职场文书
结婚保证书
2015/01/16 职场文书
Redis官方可视化工具RedisInsight安装使用教程
2022/04/19 Redis