浅谈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在多玩图片上下载妹子图的实现代码
Aug 13 Python
python使用urllib模块开发的多线程豆瓣小站mp3下载器
Jan 16 Python
python进阶教程之函数对象(函数也是对象)
Aug 30 Python
Python中关键字nonlocal和global的声明与解析
Mar 12 Python
python利用sklearn包编写决策树源代码
Dec 21 Python
Python requests发送post请求的一些疑点
May 20 Python
如何在django里上传csv文件并进行入库处理的方法
Jan 02 Python
Python基于DB-API操作MySQL数据库过程解析
Apr 23 Python
详解pyqt5的UI中嵌入matplotlib图形并实时刷新(挖坑和填坑)
Aug 07 Python
Python爬取网页信息的示例
Sep 24 Python
python Matplotlib基础--如何添加文本和标注
Jan 26 Python
Python中glob库实现文件名的匹配
Jun 18 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
服务器端解压缩zip的脚本
2006/12/22 PHP
用PHP为SHOPEX增加日志功能代码
2010/07/02 PHP
php中的ini配置原理详解
2014/10/14 PHP
PHP解决中文乱码
2017/04/28 PHP
JS打印组合功能
2016/08/04 Javascript
详解如何在NodeJS项目中优雅的使用ES6
2017/04/22 NodeJs
Node.js中多进程模块Cluster的介绍与使用
2017/05/27 Javascript
JavaScript实现三级联动效果
2017/07/15 Javascript
极简主义法编写JavaScript类
2017/11/02 Javascript
vue 实现在函数中触发路由跳转的示例
2018/09/01 Javascript
微信小程序实现提交input信息到后台的方法示例
2019/01/19 Javascript
JS栈stack类的实现与使用方法示例
2019/01/31 Javascript
微信小程序实现获取小程序码和二维码java接口开发
2019/03/29 Javascript
js字符串类型String常用操作实例总结
2019/07/05 Javascript
关于vue-cli3打包代码后白屏的解决方案
2020/09/02 Javascript
详解微信小程序(Taro)手动埋点和自动埋点的实现
2021/03/02 Javascript
[01:00:04]DOTA2上海特级锦标赛B组小组赛#1 Alliance VS Spirit第二局
2016/02/26 DOTA
跟老齐学Python之编写类之二方法
2014/10/11 Python
Python标准库之collections包的使用教程
2017/04/27 Python
python简单商城购物车实例代码
2018/03/15 Python
Python实现的求解最小公倍数算法示例
2018/05/03 Python
Python中安装easy_install的方法
2018/11/18 Python
python中的print()输出
2019/04/12 Python
利用python和百度地图API实现数据地图标注的方法
2019/05/13 Python
python格式化输出保留2位小数的实现方法
2019/07/02 Python
如何使用python爬虫爬取要登陆的网站
2019/07/12 Python
Python Collatz序列实现过程解析
2019/10/12 Python
python实现名片管理器的示例代码
2019/12/17 Python
中科创达面试题
2016/12/28 面试题
初中生学习生活的自我评价
2013/11/20 职场文书
公务员综合考察材料
2014/02/01 职场文书
讲座主持词
2014/03/20 职场文书
信息技术课后反思
2014/04/27 职场文书
工作批评与自我批评范文
2014/10/16 职场文书
全陪导游词开场白
2015/05/29 职场文书
2016年机关单位节能宣传周活动总结
2016/04/05 职场文书