浅谈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实现下载网易云音乐的高清MV
Mar 16 Python
Python使用numpy模块创建数组操作示例
Jun 20 Python
python实现俄罗斯方块游戏
Mar 25 Python
Sanic框架配置操作分析
Jul 17 Python
Python这样操作能存储100多万行的xlsx文件
Apr 16 Python
python使用参数对嵌套字典进行取值的方法
Apr 26 Python
PyQt5使用QTimer实现电子时钟
Jul 29 Python
Python如何通过Flask-Mail发送电子邮件
Jan 29 Python
Python3监控疫情的完整代码
Feb 20 Python
python使用Geany编辑器配置方法
Feb 21 Python
套娃式文件夹如何通过Python批量处理
Aug 23 Python
python安装及变量名介绍详解
Dec 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
nginx+php-fpm配置文件的组织结构介绍
2012/11/07 PHP
基于PHP后台的Android新闻浏览客户端
2016/05/23 PHP
php静态成员方法和静态的成员属性的使用方法
2017/10/26 PHP
JavaScript初学者应注意的七个细节详细介绍
2012/12/27 Javascript
JavaScript实现的内存数据库LokiJS介绍和入门实例
2014/11/17 Javascript
让JavaScript中setTimeout支持链式操作的方法
2015/06/19 Javascript
avalon js实现仿google plus图片多张拖动排序附源码下载
2015/09/24 Javascript
JavaScript简单获取系统当前时间完整示例
2016/08/02 Javascript
vue.js实现仿原生ios时间选择组件实例代码
2016/12/21 Javascript
d3.js入门教程之数据绑定详解
2017/04/28 Javascript
深入探究AngularJs之$scope对象(作用域)
2017/07/20 Javascript
使用jQuery实现鼠标点击左右按钮滑动切换
2017/08/04 jQuery
捕获未处理的Promise错误方法
2017/10/13 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
JS实现键值对遍历json数组功能示例
2018/05/30 Javascript
实例讲解React 组件生命周期
2020/07/08 Javascript
JavaScript JSON使用原理及注意事项
2020/07/30 Javascript
vscode自定义vue模板的实现
2021/01/27 Vue.js
Python 内置函数memoryview(obj)的具体用法
2017/11/23 Python
python使用turtle绘制分形树
2018/06/22 Python
matplotlib实现热成像图colorbar和极坐标图的方法
2018/12/13 Python
pytorch实现MNIST手写体识别
2020/02/14 Python
浅谈keras2 predict和fit_generator的坑
2020/06/17 Python
Python常用数据分析模块原理解析
2020/07/20 Python
CSS中垂直居中的简单实现方法
2015/07/06 HTML / CSS
Rosetta Stone官方网站:语言学习
2019/01/05 全球购物
最新远光软件笔试题面试题内容
2013/11/08 面试题
Java中会存在内存泄漏吗,请简单描述
2016/12/22 面试题
探矿工程师自荐信
2014/01/24 职场文书
2014年体检中心工作总结
2014/12/23 职场文书
教师个人培训总结
2015/02/11 职场文书
幼儿园辞职信
2015/05/13 职场文书
费用申请报告范文
2015/05/15 职场文书
Python使用random模块实现掷骰子游戏的示例代码
2021/04/29 Python
Python中else的三种使用场景
2021/06/16 Python
六个好看实用的 HTML + CSS 后台登录入口页面
2022/04/28 HTML / CSS