RFC: Proposal: Deterministic Object Destruction

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sat Mar 3 23:20:31 EST 2018


On Sat, 03 Mar 2018 18:19:37 -0800, Ooomzay wrote:

>> def function():
>>     x = open_resource()
>>     process(x)
>>     # and we're done with x now, but too lazy to explicitly close it
>>     sleep(10000) # Simulate some more work. Lots of work. 
>>     return
>>     # and finally x is closed (2.8 hours after you finished using it)
>> 
>> The answer in C++ is "well don't do that then". The answer is Python
>> is, "don't be so lazy, just use a with statement".
> 
> The answer in C++ would be to say "don't be so lazy just put the x
> manipulation in a function or sub-block". 

Right -- so you still have to think about resource management. The 
premise of this proposal is that RAII means you don't have to think about 
resource management, it just happens, but that's not really the case.


> The answer with Python + this
> PEP would be "don't be so lazy just put the x manipulation in a function
> or explicitly del x" ...no new syntax.

Sure -- but it doesn't gain you anything we don't already have.

It imposes enormous burdens on the maintainers of at least five 
interpreters (CPython, Stackless, Jython, IronPython, PyPy) all of which 
will need to be re-written to have RAII semantics guaranteed; it will 
probably have significant performance costs; and at the end of the day, 
the benefit over using a with statement is minor.

(Actually, I'm not convinced that there is *any* benefit. If anything, I 
think it will be a reliability regression -- see below.)


>> If you want deterministic closing of resources, with statements are the
>> way to do it.
>> 
>> def function():
>>     with open_resource() as x:
>>         process(x)
>>     # and x is guaranteed to be closed
> 
> What a palava!

I don't know that word, and neither do any of my dictionaries. I think 
the word you might mean is "pelaver"?

Palaver \Pa*la"ver\, n. [Sp. palabra, or Pg. palavra, fr. L.
   parabola a comparison, a parable, LL., a word. See
   Parable.]
   [1913 Webster]
   1. Talk; conversation; esp., idle or beguiling talk; talk
      intended to deceive; flattery.



In any case, you might not like with statements, but I think they're 
infinitely better than:

def meaningless_function_that_exists_only_to_manage_resource():
    x = open_resource()
    process(x)

def function():
    meaningless_function_that_exists_only_to_manage_resource()
    sleep(10000)  # simulate a long-running function


Or worse:

def function():
    if True:
        # Do this just to introduce a new scope, as in C++
        # (but not Python today)
        x = open_resource()
        process(x)
    sleep(10000)  # simulate a long-running function


In other words, your solutions are just as much manual resource 
management as the with statement. The only differences are:

- instead of explicitly using a dedicated syntax designed for 
  resource management, you're implicitly using scope behaviour;

- the with block is equivalent to a try...finally, and so it is
  guaranteed to close the resource even if an exception occurs;
  your solution isn't.

If process(x) creates a non-local reference to x, and then raises an 
exception, and that exception is caught elsewhere, x will not go out of 
scope and won't be closed. A regression in the reliability of the code.

(I'm moderately confident that this failure of RAII to deliver what it 
promises is possible in C++ too.)



-- 
Steve




More information about the Python-list mailing list