浅谈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的Django框架中设置日期和字段可选的方法
Jul 17 Python
Python 常用string函数详解
May 30 Python
python实现ID3决策树算法
Dec 20 Python
Python网络爬虫神器PyQuery的基本使用教程
Feb 03 Python
numpy 进行数组拼接,分别在行和列上合并的实例
May 08 Python
15行Python代码实现网易云热门歌单实例教程
Mar 10 Python
Python函数装饰器常见使用方法实例详解
Mar 30 Python
Django的models模型的具体使用
Jul 15 Python
python的pstuil模块使用方法总结
Jul 26 Python
Python代码实现http/https代理服务器的脚本
Aug 12 Python
Python基础之变量基本用法与进阶详解
Jan 03 Python
Python常用模块函数代码汇总解析
Aug 31 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 判断常量,变量和函数是否存在
2009/04/26 PHP
PHP程序员面试 切忌急功近利(更需要注重以后的发展)
2010/09/01 PHP
php仿微信红包分配算法的实现方法
2016/05/13 PHP
Yii2框架类自动加载机制实例分析
2018/05/02 PHP
php empty 函数判断结果为空但实际值却为非空的原因解析
2018/05/28 PHP
php对mongodb的扩展(初识如故)
2012/11/11 Javascript
JS中数组Array的用法示例介绍
2014/02/20 Javascript
JS常用表单验证方法总结
2014/05/22 Javascript
javascript实现回到顶部特效
2015/05/06 Javascript
jquery实现点击展开列表同时隐藏其他列表
2015/08/10 Javascript
Nodejs Express4.x开发框架随手笔记
2015/11/23 NodeJs
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
2015/12/10 Javascript
JavaScript利用正则表达式替换字符串中的内容
2016/12/12 Javascript
JS控件bootstrap suggest plugin使用方法详解
2017/03/25 Javascript
JS原生轮播图的简单实现(推荐)
2017/07/22 Javascript
javaScript 连接打印机,打印小票的实例
2017/12/29 Javascript
Nodejs调用Dll模块的方法
2018/09/17 NodeJs
js实现小时钟效果
2020/03/25 Javascript
Python计算三角函数之asin()方法的使用
2015/05/15 Python
Python实时获取cmd的输出
2015/12/13 Python
Python获取某一天是星期几的方法示例
2017/01/17 Python
python删除本地夹里重复文件的方法
2020/11/19 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
tensorflow下的图片标准化函数per_image_standardization用法
2020/06/30 Python
利用python爬取有道词典的方法
2020/12/08 Python
Python 用__new__方法实现单例的操作
2020/12/11 Python
浅析HTML5:'data-'属性的作用
2018/01/23 HTML / CSS
Banggood官网:面向全球客户的综合商城
2017/04/19 全球购物
The Body Shop美体小铺西班牙官网:天然化妆品
2019/06/21 全球购物
威盛公司软件C++工程师笔试题面试题
2012/07/16 面试题
国培教师自我鉴定
2014/02/12 职场文书
顶碗少年教学反思
2014/02/21 职场文书
初中毕业生的自我评价
2014/03/03 职场文书
冬季施工防火方案
2014/05/17 职场文书
党的群众路线教育实践活动个人自我剖析材料
2014/10/07 职场文书
德劲DE1107指针试高灵敏度全波段收音机机评
2022/04/05 无线电