开发者

i need to do object cleanup when instance is deleted, but not on exit. can an instance delete itself?

开发者 https://www.devze.com 2023-01-12 18:50 出处:网络
i\'d like to do some cleanup whenever an instance is deleted at runtime, but not during garbage collection that happens on exit.

i'd like to do some cleanup whenever an instance is deleted at runtime, but not during garbage collection that happens on exit.

in the example below, when c is deleted, a file is removed, and this is what i want; however, that file is also removed when the program exits, and this is NOT what i want.

class C:
  def __del__(self):
    os.remove(self.filename)

c=C()
del c

can i tie开发者_运维技巧 runtime instance deletion with a block of statements, but not execute that same block when python exits?

thanks.


CPython uses reference counting and only runs a fully-fledged GC (that removes cyclic references) once in a while, c = C(); del c would trigger the new C to be gc'd right away, yeah. As for __del__ and interpreter exit, the docs say:

It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.

But it seems impossible to be sure. Plus (admittedly, this has little relevance in practive), other implementations like Jython and IronPython don't use reference counting = object destruction/finalization is less predictable (or - in theory - may not occur at all, at least in .NET).

Anyway: this requirement (only executing __del__ when gc'd normally, not on interpreter exit) really smells. Could you elaborate on why you need to care about this?

You might want a context manager.


What you want to do is not so pythonic (and I don't think it's possible). Deleting instances at runtime should usally not be needed.

You could use your own function instead of del at runtime:

def rem(object):
    object.__remove()

class C:
    def __remove(self):
        os.remove(self.filename)

c=C()
rem(c)

Or you could implent deletion as instance method (more pythonic!):

class C:
    def remove(self):
        os.remove(self.filename)

c=C()
c.remove()

Or you could destroy the deletion handler at programs end:

class C:
    instances = []

    def __init__(self):
        C.instances.append(self)

    def __del__(self):
        C.instances.remove(self)
        os.remove(self.filename)

c = C()
del c

# ... do something ...

for c in C.instances:
    del c.__del__
0

精彩评论

暂无评论...
验证码 换一张
取 消