[Python-Dev] Object finalization for local (ie function) scopes
Moore, Paul
Paul.Moore at atosorigin.com
Mon Jun 14 05:17:58 EDT 2004
From: Oliver Schoenborn
>> However, this is probably the time to ask for a PEP that properly
>> describes the API and the semantics of the feature.
> In time... I'd like a couple more opinions if possible. I'm
> surprised there hasn't been more given how fundamental the problem
> of RAII is in Python.
It's not at all clear that there *is* a "problem of RAII" in Python.
Regardless, you may want to look at PEP 310, and the (extensive)
threads on python-dev which it spawned, for an alternative view of
the issue.
>From my perspective, the RAII idiom is a very nice approach in C++,
but it's not at all clear if it can be made to translate cleanly into
Python, for fundamental semantic reasons (C++ deallocates on scope
exit, regardless of outstanding references, which creates the issue of
dangling reference, but makes RAII possible).
The things I like about RAII:
1. Resource management is concentrated in one place, the creation of
the object. (OK, the object's class definition needs to contain the
acquisition and release code, but that's normal encapsulation, IMO).
2. First-in, last-out ordering is enforced by the scope rules of the
language.
3. Timing issues over windows where interrupts can result in acquired
resources not being released, or partially-acquired resources being
released, are avoided by the language's semantics of initialisation.
PEP 310 addresses points (1) and (3) - although (3) is only alluded to
in the "Implementation notes" section, and isn't clearly stated as a
required feature of the construct in the main PEP body.
Point (2) is the one that often causes code to look most "messy". Nested
try/finally (or PEP 310 with) blocks can obscure code structure. Consider
lock.acquire()
try:
f = open(...)
try:
something_else.reserve()
try:
# The real code goes here!
finally:
something_else.release()
finally:
f.close()
finally:
lock.release()
However, the general consensus seems to be (a) that such code needs
refactoring into separate functions, each of which only acquires a single
resource, and (b) that if you *really* need to acquire 3 resources like
this, you can write a user-defined class which encapsulates this need
as a "combined" resource:
class StuffINeed:
"Missing code to handle failures during __enter__ or __exit__"
def __init__(self, lock, something_else):
self.lock = lock
self.something_else = something_else
self.f = None
def __enter__(self):
"PEP 310 method"
self.lock.acquire()
self.f = open(...)
self.something_else.reserve()
def __exit__(self):
"PEP 310 method"
self.something_else.release()
self.f.close()
self.lock.release()
[Because of the "Missing code..." comment, a generalised version of such
a class may be a useful addition to the standard library in combination
with PEP 310]
Sorry - that went on longer than anticipated. To summarise, I think you
should consider whether PEP 310 is what you need (it's probably mode
Pythonic than overloading __del__ the way C++ does), and if so, put your
energy into assisting the progress of that PEP.
Paul.
__________________________________________________________________________
This e-mail and the documents attached are confidential and intended
solely for the addressee; it may also be privileged. If you receive this
e-mail in error, please notify the sender immediately and destroy it.
As its integrity cannot be secured on the Internet, the Atos Origin group
liability cannot be triggered for the message content. Although the
sender endeavours to maintain a computer virus-free network, the sender
does not warrant that this transmission is virus-free and will not be
liable for any damages resulting from any virus transmitted.
__________________________________________________________________________
More information about the Python-Dev
mailing list