浅谈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判断字符串与大小写转换
Jun 08 Python
Python中的左斜杠、右斜杠(正斜杠和反斜杠)
Aug 30 Python
浅谈function(函数)中的动态参数
Apr 30 Python
Python实现将Excel转换为json的方法示例
Aug 05 Python
使用Python自动化破解自定义字体混淆信息的方法实例
Feb 13 Python
django与小程序实现登录验证功能的示例代码
Feb 19 Python
python3发送邮件需要经过代理服务器的示例代码
Jul 25 Python
Python使用pymysql模块操作mysql增删改查实例分析
Dec 19 Python
Python无损压缩图片的示例代码
Aug 06 Python
Python用Jira库来操作Jira
Dec 28 Python
python UDF 实现对csv批量md5加密操作
Jan 01 Python
python数字图像处理之图像自动阈值分割示例
Jun 28 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环境――Appserv
2006/12/13 PHP
php 去除html标记--strip_tags与htmlspecialchars的区别详解
2013/06/26 PHP
php引用传值实例详解学习
2013/11/06 PHP
学习php设计模式 php实现原型模式(prototype)
2015/12/07 PHP
一些有关检查数据的JS代码
2006/09/07 Javascript
扩展JavaScript功能的正确方法(译文)
2012/04/12 Javascript
JS批量修改PS中图层名称的方法
2014/01/26 Javascript
jquery实现瀑布流效果分享
2014/03/26 Javascript
基于Css3和JQuery实现打字机效果
2015/08/11 Javascript
Jqgrid之强大的表格插件应用
2015/12/02 Javascript
jQuery layui常用方法介绍
2016/07/25 Javascript
用v-html解决Vue.js渲染中html标签不被解析的问题
2016/12/14 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
2017/03/06 Javascript
element-ui 设置菜单栏展开的方法
2018/08/22 Javascript
配置node服务器并且链接微信公众号接口配置步骤详解
2019/06/21 Javascript
解决Layui中layer报错的问题
2019/09/03 Javascript
手把手带你搭建一个node cli的方法示例
2020/08/07 Javascript
Antd的table组件表格的序号自增操作
2020/10/27 Javascript
跟老齐学Python之玩转字符串(3)
2014/09/14 Python
python搭建虚拟环境的步骤详解
2016/09/27 Python
Python使用jsonpath-rw模块处理Json对象操作示例
2018/07/31 Python
Python学习笔记之文件的读写操作实例分析
2019/08/07 Python
python中的数组赋值与拷贝的区别详解
2019/11/26 Python
浅析python标准库中的glob
2020/03/13 Python
去除python中的字符串空格的简单方法
2020/12/22 Python
HTML5录音实践总结(Preact)
2020/05/07 HTML / CSS
联想印度官方网上商店:Lenovo India
2019/08/24 全球购物
linux下进程间通信的方式
2013/01/23 面试题
幼儿园老师辞职信
2014/01/20 职场文书
《日月潭》教学反思
2014/02/28 职场文书
汽车促销活动方案
2014/03/31 职场文书
学习走群众路线心得体会
2014/11/05 职场文书
党支部书记岗位职责
2015/02/15 职场文书
缅怀先烈主题班会
2015/08/14 职场文书
Java基础之线程锁相关知识总结
2021/06/30 Java/Android
shell进度条追踪指令执行时间的场景分析
2022/06/16 Servers