python - When does a module scope variable reference get released by the interpreter? -


i'm trying implement clean-up routine in utility module have. in looking around solutions problem, settled on using weakref callback cleanup. however, i'm concerned won't work expected because of strong reference object within same module. illustrate:

foo_lib.py

class foo(object):      _refs = {}      def __init__(self, x):          self.x = x         self._weak_self = weakref.ref(self, foo._clean)         foo._refs[self._weak_self] = x      @classmethod     def _clean(cls, ref):          print 'cleaned %s' % cls._refs[ref]  foo = foo() 

other classes reference foo_lib.foo. did find old document 1.5.1 sort of references concerns (http://www.python.org/doc/essays/cleanup/) nothing makes me comfortable foo released in such way callback triggered reliably. can point me towards docs clear question me?

the right thing here explicitly release strong reference @ point, rather counting on shutdown it.

in particular, if module released, globals released… but doesn't seem documented anywhere module released. so, there may still reference object @ shutdown. and, martijn pieters pointed out:

it not guaranteed __del__() methods called objects still exist when interpreter exits.

however, if can ensure there no (non-weak) references object time before interpreter exits, can guarantee cleanup runs.

you can use atexit handlers explicitly clean after yourself, can explicitly before falling off end of main module (or calling sys.exit, or finishing last non-daemon thread, or whatever). simplest thing take entire main function , wrap in with or try/finally.

or, more simply, don't try put cleanup code __del__ methods or weakref callbacks; put cleanup code with or finally or atexit.


in comment on answer:

what i'm trying close out subprocess kept open timer, needs nuked when program exits. "reliable" way start daemonic subprocess monitor , kill other process separately?

the usual way kind of thing replace timer signalable outside. without knowing app architecture , kind of timer you're using (e.g., single-threaded async server reactor kicks timer vs. single-threaded async gui app os timer message kicks timer vs. multi-threaded app timer thread sleeps between intervals vs. …), it's hard explain more specifically.

meanwhile, may want @ whether there's simpler way handle subprocesses. example, maybe using explicit process group, , killing process group instead of process (which kill of children, on both windows , unix… although details different)? or maybe give subprocess pipe , have quit when other end of pipe goes down?


note documentation gives no guarantees order in left-over references deleted, if are. in fact, if you're using cpython, py_finalize says it's "done in random order".

the source interesting. it's not explicitly randomized, , it's not entirely arbitrary. first gc collect until nothing left, finalizes gc itself, pyimport_cleanup (which sys.modules.clear()), there's collect commented out (with discussion why), , _pyimport_fini (which defined "for internal use only").

but means that, assuming module holding (non-weak) reference(s) object, , there no unbreakable cycles involving module itself, module cleaned @ shutdown, drop last reference object, causing cleaned well. (of course cannot count on other builtins, extension modules, , things have direct reference still existing @ point… code above should fine, because foo can't cleaned before foo, , doesn't rely on other non-builtins.)

keep in mind cpython-specific—and in fact cpython 3.3-specific; want read relevant equivalent source version sure. again, documentation explicitly says things deleted "in random order", that's have expect if don't want rely on implementation-specific behavior.


of course cleanup code still isn't guaranteed called. example, unhandled signal (on unix) or structured exception (on windows) kill interpreter without giving chance clean anything. , if write handlers that, pull power cord. so, if need robust design, need interruptable without cleanup @ point (by journaling, using atomic file operations, protocols explicit acknowledgement, etc.).


Comments

Popular posts from this blog

ios - UICollectionView Self Sizing Cells with Auto Layout -

node.js - ldapjs - write after end error -

DOM Manipulation in Wordpress (and elsewhere) using php -