浅谈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使用requests发送POST请求实例代码
Jan 25 Python
Python星号*与**用法分析
Feb 02 Python
详谈python3中用for循环删除列表中元素的坑
Apr 19 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
May 16 Python
Python实现拷贝/删除文件夹的方法详解
Aug 29 Python
opencv python统计及绘制直方图的方法
Jan 21 Python
详解python播放音频的三种方法
Sep 23 Python
如何基于Python实现电子邮件的发送
Dec 16 Python
pyinstaller打包单文件时--uac-admin选项不起作用怎么办
Apr 15 Python
解决Keras中循环使用K.ctc_decode内存不释放的问题
Jun 29 Python
Python字符串split及rsplit方法原理详解
Jun 29 Python
django美化后台django-suit的安装配置操作
Jul 12 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
BBS(php & mysql)完整版(一)
2006/10/09 PHP
PHP中使用imagick实现把PDF转成图片
2015/01/26 PHP
PHP 获取ip地址代码汇总
2015/07/05 PHP
PHP与jquery实时显示网站在线人数实例详解
2016/12/02 PHP
laravel ORM 只开启created_at的几种方法总结
2018/01/29 PHP
360搜索引擎自动收录php改写方案
2018/04/28 PHP
可兼容php5与php7的cURL文件上传功能实例分析
2018/05/11 PHP
PHP simplexml_load_string()函数实例讲解
2019/02/03 PHP
基于jquery的一个图片hover的插件
2010/04/24 Javascript
JavaScript数组常用方法
2015/03/02 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
2015/08/20 Javascript
jquery遍历json对象集合详解
2016/05/18 Javascript
jQuery Ajax 全局调用封装实例代码详解
2016/06/02 Javascript
15位和18位身份证JS校验的简单实例
2016/07/18 Javascript
KVM虚拟化技术之使用Qemu-kvm创建和管理虚拟机的方法
2016/10/05 Javascript
基于nodejs实现微信支付功能
2017/12/20 NodeJs
基于Vue 2.0 监听文本框内容变化及ref的使用说明介绍
2018/08/24 Javascript
Vue2.0使用嵌套路由实现页面内容切换/公用一级菜单控制页面内容切换(推荐)
2019/05/08 Javascript
基于js实现的图片拖拽排序源码实例
2020/11/04 Javascript
[01:59]DOTA2首部纪录片《Free to play》预告片
2014/03/12 DOTA
[01:04:48]VGJ.S vs TNC Supermajor 败者组 BO3 第一场 6.6
2018/06/07 DOTA
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
[46:59]完美世界DOTA2联赛PWL S2 GXR vs Ink 第二场 11.19
2020/11/20 DOTA
python处理大数字的方法
2015/05/27 Python
基于asyncio 异步协程框架实现收集B站直播弹幕
2016/09/11 Python
python+selenium开发环境搭建图文教程
2017/08/11 Python
Python安装tar.gz格式文件方法详解
2020/01/19 Python
Python下划线5种含义代码实例解析
2020/07/10 Python
css3实现文字首尾衔接跑马灯的示例代码
2020/10/16 HTML / CSS
如何将整数int转换成字串String
2014/03/21 面试题
国际会议邀请函范文
2014/01/16 职场文书
酒店销售经理岗位职责
2014/01/31 职场文书
中学教师教学工作总结
2015/08/13 职场文书
中国梦宣传标语口号
2015/12/26 职场文书
openstack中的rpc远程调用的方法
2021/07/09 Python
MySQL中的引号和反引号的区别与用法详解
2021/10/24 MySQL