python如何在循环引用中管理内存

yipeiwu_com7年前Python基础

python中通过引用计数来回收垃圾对象,在某些环形数据结构(树,图……),存在对象间的循环引用,比如树的父节点引用子节点,子节点同时引用父节点,此时通过del掉引用父子节点,两个对象不能被立即释放

需求:

如何解决此类的内存管理问题?

如何查询一个对象的引用计数?

       import sys

       sys.getrefcount(obj)

       # 查询引用计数必多 1 ,因为object也引用 查询对象

如何解决内存管理问题?

  • 通过weakref,进行弱引用,当del时候,不再引用,在引用方添加weakref.ref(引用obj);
  • 使用引用的时候,需要用到函数调用的形式
#!/usr/bin/python3
 
import weakref
import sys
 
 
class Data(object):
 def __init__(self, value, owner):
  self.value = value
   
  # 声明弱引用,owner为Node类本身
  self.owner = weakref.ref(owner)
  
 # 通过函数调用的方式访问引用对象
 def __str__(self):
  return "%s's data, value is %s" % (self.owner(), self.value)
  
 def __del__(self):
  print('in_data.__del__')
 
 
class Node(object):
 def __init__(self, value):
   
  # 把类本身,也当做参数传入Data类中
  self.data = Data(value, self)
  
 # 自定义对象名,容易辨认
 def __str__(self):
  return 'Node'
  
 def __del__(self):
  print('in_node.__del__')
  
 
if __name__ == '__main__':
 node = Node(100)
 print(node.data)
  
 # 打印node对象的引用计数
 print(sys.getrefcount(node) - 1)
  
 # 当删除node对象时候,Data实例对象在引用计算为0也相应释放
 del node
  
 input('del done >>>>>')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持【听图阁-专注于Python设计】。

相关文章

python 多进程共享全局变量之Manager()详解

Manager支持的类型有 list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue...

使用 Python 实现简单的 switch/case 语句的方法

在Python中是没有Switch / Case语句的,很多人认为这种语句不够优雅灵活,在Python中用字典来处理多条件匹配问题字典会更简单高效,对于有一定经验的Python玩家不得不...

PyQt5固定窗口大小的方法

PyQt5固定窗口大小的方法

直接以数值固定大小 根据屏幕大小固定大小 禁止最大化按钮 MainWindow.setWindowFlags(QtCore.Qt.WindowMinimizeButtonHint...

对python dataframe逻辑取值的方法详解

我遇到的一个小需求,就是希望通过判断pandas dataframe中一列的值在两个条件范围(比如下面代码中所描述的逻辑,取小于u-3ε和大于u+3ε的值),然后取出dataframe中...

Python提取频域特征知识点浅析

Python提取频域特征知识点浅析

在多数的现代语音识别系统中,人们都会用到频域特征。梅尔频率倒谱系数(MFCC),首先计算信号的功率谱,然后用滤波器和离散余弦变换的变换来提取特征。本文重点介绍如何提取MFCC特征。 首先...