RFC: Proposal: Deterministic Object Destruction

ooomzay at gmail.com ooomzay at gmail.com
Thu Mar 1 18:38:15 EST 2018


On Thursday, March 1, 2018 at 12:15:57 AM UTC, Paul Rubin wrote:
> RAII is similar to Python's "with" statement. So it sounds like OP
> wants to replace one "malignant carbuncle" with another one. 

I would like to understand why you think RAII is not substantially more 
pythonic than "With". Below I have sketched out a File-like resource 
management scenario using both PEP343 and RAII idioms for comparison. 
First lets look at the implementation of the competing resource management 
classes:-
class PEP343FileAccess():
 '''
 A File Access-like resource with self-contained Context Manager for use 
 with "with".
 This could be acheived with two separate classes but I don't think that 
 adds anything except lines of code.
 '''
	
 # Structors
 
 def __init__(self, filename, mode):
 self.filename = filename
 self.mode = mode 
 self.handle = None
 # dummy file content accessible only when handle is not None
 self.lines = ['one', 'two', 'three'] 
 # PEP343 Context Manager compliance
 
 def __enter__(self):
 self.handle = low_level_file_open(self.filename, self.mode) # fictitious
 return self
 
 def __exit__(self, extype, exvalue, extraceback):
 low_level_file_close(self.handle) # fictitious function
 self.handle = None
 
 # Example methods
 def __iter__(self):
 assert self.handle, "File has been closed"
 for line in self.lines: 
 yield line
 def write(self, line):
 assert self.handle, "File has been closed"
 self.lines.append(line)
class RAIIFileAccess():
 '''File Access-like Resource using RIAA idiom'''
 
 # Structors
 def __init__(self, filename, mode):
 self.handle = low_level_file_open(filename, mode) # fictitious
 # dummy content accessible as long as the object exists (invariant)
 self.lines = ['one', 'two', 'three'] 
 
 def __del__(self): 
 low_level_file_close(self.handle) # fictitious function
 # Example methods
 def __iter__(self):
 for line in self.lines:
 yield line
 def write(self, line):
 self.lines.append(line)
What I see is that PEP343 requires two new methods: __enter__ & __exit__.
RIAA requires no new methods.
RIAA resources are invariant: If you have a reference to it you can use it.
PEP343 resources can not be invariant: To be robust the enter/exit state
must be tracked and checked. (assert self.handle in the example)
Now lets look at example resource usage:-
def pep343_example():
 with PEP343FileAccess("src.txt", 'r') as src, 
 PEP343FileAccess("dst.txt", 'w') as dst:
 for line in src: 
 dst.write(line)
def raii_example():
 
 src = RAIIFileAccess("src.txt", 'r')
 dst = RAIIFileAccess("dst.txt", 'w')
 for line in src:
 dst.write(line)
PEP343 requires specialised "with" syntax, RIAA requires no new syntax.
Furthermore, although src & dst objects are still accessible outside the 
PEP343 "with" block they are not in a usable state (not invariant).
In the RIAA case the resources are guaranteed to be in a usable state as long 
as any reference exists (invariant). References can also be safely
passed around.The resource will be freed/closed when the last man has finished 
with it, even in the face of exceptions.


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /