python删除对象引用_Python:删除自引用对象

我想问一下如何在Python中删除具有自引用的对象.

让我们考虑一个类,这是一个简单的示例,它知道何时创建和删除它:

#!/usr/bin/python

class TTest:

def __init__(self):

self.sub_func= None

print 'Created',self

def __del__(self):

self.sub_func= None

print 'Deleted',self

def Print(self):

print 'Print',self

此类具有一个变量self.sub_func,我们假设要为其分配一个函数.我想将使用TTest实例的函数分配给self.sub_func.请参阅以下情况:

def SubFunc1(t):

t.Print()

def DefineObj1():

t= TTest()

t.sub_func= lambda: SubFunc1(t)

return t

t= DefineObj1()

t.sub_func()

del t

结果是:

Created <__main__.TTest instance at 0x7ffbabceee60>

Print <__main__.TTest instance at 0x7ffbabceee60>

也就是说,尽管我们执行了“ del t”,但并未删除t.

我猜想原因是t.sub_func是一个自引用对象,因此t的引用计数器在“ del t”处不会变为零,因此t不会被垃圾收集器删除.

为了解决这个问题,我需要插入

t.sub_func= None

在“ del t”之前;在这个时候,输出是:

Created <__main__.TTest instance at 0x7fab9ece2e60>

Print <__main__.TTest instance at 0x7fab9ece2e60>

Deleted <__main__.TTest instance at 0x7fab9ece2e60>

但这很奇怪. t.sub_func是t的一部分,所以我不想在删除t时担心清除t.sub_func.

您能否告诉我您是否知道一个好的解决方案?

解决方法:

如何确保引用循环中的对象不再不可访问时被删除?最简单的解决方案是不定义__del__方法.很少(如果有的话)的类需要__del__方法. Python无法保证何时或什至将调用__del__方法.

有几种方法可以缓解此问题.

>使用函数而不是包含并检查弱引用的lambda.每次调用函数时,都需要显式检查对象是否仍然存在.

>为每个对象创建一个唯一的类,以便我们可以将该函数存储在一个类上,而不是作为猴子修补函数.这可能会使内存变大.

>定义一个知道如何获取给定函数并将其转换为方法的属性.我个人最喜欢的是,它非常近似于如何从类的未绑定方法中创建绑定方法.

使用弱引用

import weakref

class TTest:

def __init__(self):

self.func = None

print 'Created', self

def __del__(self):

print 'Deleted', self

def print_self(self):

print 'Print',self

def print_func(t):

t.print_self()

def create_ttest():

t = TTest()

weak_t = weakref.ref(t)

def func():

t1 = weak_t()

if t1 is None:

raise TypeError("TTest object no longer exists")

print_func(t1)

t.func = func

return t

if __name__ == "__main__":

t = create_ttest()

t.func()

del t

创建一个独特的班级

class TTest:

def __init__(self):

print 'Created', self

def __del__(self):

print 'Deleted', self

def print_self(self):

print 'Print',self

def print_func(t):

t.print_self()

def create_ttest():

class SubTTest(TTest):

def func(self):

print_func(self)

SubTTest.func1 = print_func

# The above also works. First argument is instantiated as the object the

# function was called on.

return SubTTest()

if __name__ == "__main__":

t = create_ttest()

t.func()

t.func1()

del t

使用属性

import types

class TTest:

def __init__(self, func):

self._func = func

print 'Created', self

def __del__(self):

print 'Deleted', self

def print_self(self):

print 'Print',self

@property

def func(self):

return types.MethodType(self._func, self)

def print_func(t):

t.print_self()

def create_ttest():

def func(self):

print_func(self)

t = TTest(func)

return t

if __name__ == "__main__":

t = create_ttest()

t.func()

del t

标签:self-reference,python

来源: https://codeday.me/bug/20191028/1955429.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值