python对象类型在内存中怎样存放_python类与对象-如何在环状数据结构中管理内存...

如何在环状数据结构中管理内存

问题举例

在python中,垃圾回收器通过引用计数来回收垃圾对象,

在某些环状数据结构(树,图...),存在对象间的循环引用,比如树的父节点引用子节点,

子节点同时引用父节点。测试同时del掉引用父子节点,两个对象不能被立即回收。

分析

当一个对象引用计数为0,或者只剩下弱引用时,这个对象会被释放。

类中有一个内置方法__del__,这个方法会在类对象释放时调用。

来个栗子

classA:def __del__(self):print("__del__")

a1=A()

a2= a1;

说明:

(1)A创建创建的对象有两个计数引用(a1和a2)

(2)当我们通过python -i test.py加载并运行这个文件到交互解释器中,__del__方法并没有被调用

(3)但是如果我们把a1, a2都指向别的对象时,A创建的对象引用计数为0,这时对象就会被释放

如下

classA:def __del__(self):print("__del__")

a1=A()

a2=a1;

a1=None

a2= None

注意:

这个时候可能有的朋友发现通过python test.py运行第一段代码时,__del__方法也会被调用,这是为什么呢?

其实答案很简单,通过python test.py运行代码后相当于直接退出程序,当一个程序退出时,这个程序内的所有变量都会被释放。

弱引用

弱引用不增加引用计数,使用弱引用访问对象得到对象引用

importweakrefclassA:def __del__(self):print("__del__")

a1=A()

a2=weakref.ref(a1)

a3=a2()print(a3 is a1) #True

解决思路

使用标准库weakref.ref,它可以创建一种能访问对象但是不增加引用计数的对象

栗子

有一个双向链表,有3个节点:1, 2, 3,变量head指向节点1,节点1右引用节点2,节点2右引用节点3,

节点3左弱引用节点2,节点2左弱引用节点1,如图

说明:当变量head指向None时,节点1对象被释放,节点1的右引用节点2被释放,节点2的右引用节点3被释放

代码

importweakrefclassNode:def __init__(self, data):

self.data=data

self._left=None

self.right=Nonedefadd_right(self, node):

self.right=node

node._left=weakref.ref(self)

@propertydefleft(self):returnself._left()def __str__(self):return 'Node:' %self.datadef __del__(self):print('in __del__: delete %s' %self)defcreate_linklist(n):

head= current = Node(1)for i in range(2, n + 1):

node=Node(i)

current.add_right(node)

current=nodereturnhead

head= create_linklist(1000)print(head.right, head.right.left)

input()

head=Noneimporttimefor _ in range(1000):

time.sleep(1)print('run...')

input('wait...')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值