浅谈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编写一个在Linux下实现截图分享的脚本的教程
Apr 24 Python
Django 连接sql server数据库的方法
Jun 30 Python
python 自动轨迹绘制的实例代码
Jul 05 Python
Python DataFrame一列拆成多列以及一行拆成多行
Aug 06 Python
Python Gitlab Api 使用方法
Aug 28 Python
树莓派极简安装OpenCv的方法步骤
Oct 10 Python
Python使用正则实现计算字符串算式
Dec 29 Python
Python sql注入 过滤字符串的非法字符实例
Apr 03 Python
python 在threading中如何处理主进程和子线程的关系
Apr 25 Python
Eclipse配置python默认头过程图解
Apr 26 Python
部署Django到阿里云服务器教程示例
Jun 03 Python
Python OpenCV超详细讲解基本功能
Apr 02 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&mysql(六)
2006/10/09 PHP
探讨如何把session存入数据库
2013/06/07 PHP
浅析PHP substr,mb_substr以及mb_strcut的区别和用法
2013/06/21 PHP
php中如何同时使用session和cookie来保存用户登录信息
2013/07/05 PHP
php 发送带附件邮件示例
2014/01/23 PHP
php使用explode()函数将字符串拆分成数组的方法
2015/02/17 PHP
PHP crypt()函数的用法讲解
2019/02/15 PHP
fancybox modal的完美解决(右上的X)
2012/10/30 Javascript
js库Modernizr的介绍和使用
2015/05/07 Javascript
如何用javascript计算文本框还能输入多少个字符
2015/07/29 Javascript
jquery判断输入密码两次是否相等
2020/04/22 Javascript
javascript常见数字进制转换实例分析
2016/04/21 Javascript
javascript事件冒泡简单示例
2016/06/20 Javascript
js实现table添加行tr、删除行tr、清空行tr的简单实例
2016/10/15 Javascript
js数字计算 误差问题的快速解决方法
2017/02/28 Javascript
vue下跨域设置的相关介绍
2017/08/26 Javascript
总结js中的一些兼容性易错的问题
2017/12/18 Javascript
Vue 前端实现登陆拦截及axios 拦截器的使用
2019/07/17 Javascript
微信小程序报错: thirdScriptError的错误问题
2020/06/19 Javascript
python单链表实现代码实例
2013/11/21 Python
Python求解平方根的方法
2015/03/11 Python
python的xpath获取div标签内html内容,实现innerhtml功能的方法
2019/01/02 Python
django项目中使用手机号登录的实例代码
2019/08/15 Python
python BlockingScheduler定时任务及其他方式的实现
2019/09/19 Python
使用phonegap克隆和删除联系人的实现方法
2017/03/31 HTML / CSS
德国奢侈品网上商城:Mytheresa
2016/08/24 全球购物
YOOX美国官方网站:全球著名的多品牌时尚网络概念店
2016/09/11 全球购物
医学专业个人求职自荐信格式
2013/09/23 职场文书
生产部统计员岗位职责
2014/01/05 职场文书
大学班级计划书
2014/04/29 职场文书
篮球比赛口号
2014/06/10 职场文书
党员评议思想汇报
2014/10/08 职场文书
个人批评与自我批评总结
2014/10/17 职场文书
初中家长评语和期望
2014/12/26 职场文书
2016年庆“七一”主题党日活动总结
2016/04/05 职场文书
Nginx域名转发https访问的实现
2021/03/31 Servers