Scope objects

R

Robert Dailey

Is it possible to create an object in Python that will clean itself up
at function exit? I realize destruction of objects may not occur
immediately and can be garbage collected, but this functionality would
still be great to have. Consider the following function:

def do_stuff():
foo = scope_object()
# Do stuff...
foo.Cleanup()

It would be nice to avoid the explicit "Cleanup()" call above, and
have 'foo' just act as if it has a C++ destructor and evoke some
method at the exit point of a function.
 
C

Chris Rebert

Is it possible to create an object in Python that will clean itself up
at function exit? I realize destruction of objects may not occur
immediately and can be garbage collected, but this functionality would
still be great to have. Consider the following function:

def do_stuff():
   foo = scope_object()
   # Do stuff...
   foo.Cleanup()

It would be nice to avoid the explicit "Cleanup()" call above, and
have 'foo' just act as if it has a C++ destructor and evoke some
method at the exit point of a function.

This is exactly what the new `with` statement lets you do. You just
need to define an appropriate context manager. With one, you can code
that as:

def do_stuff():
with scope_object() as foo:
#do stuff

More info: http://www.python.org/dev/peps/pep-0343/

Cheers,
Chris
 
S

s0suk3

Is it possible to create an object in Python that will clean itself up
at function exit? I realize destruction of objects may not occur
immediately and can be garbage collected, but this functionality would
still be great to have. Consider the following function:

def do_stuff():
    foo = scope_object()
    # Do stuff...
    foo.Cleanup()

It would be nice to avoid the explicit "Cleanup()" call above, and
have 'foo' just act as if it has a C++ destructor and evoke some
method at the exit point of a function.

I don't know what you mean by:

"I realize destruction of objects may not occur immediately and can be
garbage collected"

Aren't you just missing ordinary destructors (__del__() methods)?
These are closest to C++ destructors AFAICS. As far as I know, these
are guaranteed to be called when an object goes out of scope. (Note
that destruction and garbage collection are different operations; an
object may be destructed without being immediately garbage-collected
afterwards.)
.... def __init__(self): sys.stdout.write("Simple.__init__()\n")
.... def __del__(self): sys.stdout.write("Simple.__del__()\n")
........ s = Simple()
.... sys.stdout.write("f()\n")
.... # 's' now going out of scope...
....
Simple.__init__()
f()
Simple.__del__()

Sebastian
 
G

Gabriel Genellina

I don't know what you mean by:

"I realize destruction of objects may not occur immediately and can be
garbage collected"

Aren't you just missing ordinary destructors (__del__() methods)?
These are closest to C++ destructors AFAICS. As far as I know, these
are guaranteed to be called when an object goes out of scope. (Note
that destruction and garbage collection are different operations; an
object may be destructed without being immediately garbage-collected
afterwards.)

No, that's not how it works in Python (and I think you're mistaken for C++
too).
See http://docs.python.org/reference/datamodel.html and specially
http://docs.python.org/reference/datamodel.html#object.__del__

"Objects are never explicitly destroyed; however, when they become
unreachable they may be garbage-collected. An implementation is allowed to
postpone garbage collection or omit it altogether."

CPython uses a "reference count" scheme - an object is destroyed as soon
as it loses its last reference. Other implementations may choose another
strategy - in fact, Jython relies on garbage collection instead; object
destruction may be delayed an arbitrary amount of time. (CPython has a
garbage collector too, but its purpose is to detect and break object
cycles.)

So the OP is right - you can't rely on object destruction to perform any
cleanup; use try/finally or a with statement instead.

... def __init__(self): sys.stdout.write("Simple.__init__()\n")
... def __del__(self): sys.stdout.write("Simple.__del__()\n")
...
... s = Simple()
... sys.stdout.write("f()\n")
... # 's' now going out of scope...
...
Simple.__init__()
f()
Simple.__del__()

This behaviour isn't guaranteed and you should not rely on it. Also, try
again with:

def f():
s = Simple()
t = Simple()
s.x = t
t.x = s
sys.stdout.write("f()\n")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,919
Members
47,458
Latest member
Chris#

Latest Threads

Top