constructor - How to force deletion of a python object? -


i curious details of __del__ in python, when , why should used , shouldn't used for. i've learned hard way not 1 naively expected destructor, in not opposite of __new__ / __init__.

class foo(object):      def __init__(self):         self.bar = none      def open(self):         if self.bar != 'open':             print 'opening bar'             self.bar = 'open'      def close(self):         if self.bar != 'closed':             print 'closing bar'             self.bar = 'close'      def __del__(self):         self.close()  if __name__ == '__main__':     foo = foo()     foo.open()     del foo     import gc     gc.collect() 

i saw in documentation not guaranteed __del__() methods called objects still exist when interpreter exits.

  1. how can guaranteed foo instances existing when interpreter exits, bar closed?
  2. in code snippet above bar closed on del foo or on gc.collect()... or neither? if want finer control of details (e.g. bar should closed when object unreferenced) usual way implement that?
  3. when __del__ called guaranteed __init__ has been called? if __init__ raised?

the way close resources context managers, aka with statement:

class foo(object):    def __init__(self):     self.bar = none    def __enter__(self):     if self.bar != 'open':       print 'opening bar'       self.bar = 'open'     return self # bound `as` part    def close(self):     if self.bar != 'closed':       print 'closing bar'       self.bar = 'close'    def __exit__(self, *err):     self.close()  if __name__ == '__main__':   foo() foo:     print foo, foo.bar 

output:

opening bar <__main__.foo object @ 0x17079d0> open closing bar 

2) python's objects deleted when reference count 0. in example del foo removes last reference __del__ called instantly. gc has no part in this.

class foo(object):      def __del__(self):         print "deling", self  if __name__ == '__main__':     import gc     gc.disable() # no gc     f = foo()     print "before"     del f # f gets deleted right away     print "after" 

output:

before deling <__main__.foo object @ 0xc49690> after 

the gc has nothing deleting , other objects. it's there clean when simple reference counting not work, because of self-references or circular references:

class foo(object):     def __init__(self, other=none):         # make circular reference         self.link = other         if other not none:             other.link = self      def __del__(self):         print "deling", self  if __name__ == '__main__':     import gc     gc.disable()        f = foo(foo())     print "before"     del f # nothing gets deleted here     print "after"     gc.collect()     print gc.garbage # gc knows 2 foos garbage, won't delete                      # them because have __del__ method     print "after gc"     # break cycle , delete reference gc.garbage     del gc.garbage[0].link, gc.garbage[:]     print "done" 

output:

before after [<__main__.foo object @ 0x22ed8d0>, <__main__.foo object @ 0x22ed950>] after gc deling <__main__.foo object @ 0x22ed950> deling <__main__.foo object @ 0x22ed8d0> done 

3) lets see:

class foo(object):     def __init__(self):          raise exception      def __del__(self):         print "deling", self  if __name__ == '__main__':     f = foo() 

gives:

traceback (most recent call last):   file "asd.py", line 10, in <module>     f = foo()   file "asd.py", line 4, in __init__     raise exception exception deling <__main__.foo object @ 0xa3a910> 

objects created __new__ passed __init__ self. after exception in __init__, object typically not have name (ie f = part isn't run) ref count 0. means object deleted , __del__ called.


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -