object.enable() anti-pattern

Terry Jan Reedy tjreedy at udel.edu
Sun May 12 16:03:39 EDT 2013


On 5/12/2013 1:14 PM, Wayne Werner wrote:
> On Fri, 10 May 2013, Gregory Ewing wrote:
>
>> Wayne Werner wrote:
>>> You don't ever want a class that has functions that need to be called
>>> in a certain order to *not* crash.
>>
>> That seems like an overly broad statement. What
>> do you think the following should do?
>>
>>   f = open("myfile.dat")
>>   f.close()
>>   data = f.read()
>
> To clarify - you don't want a class that has functions that need to be
> called in a certain order with *valid input* in order to not crash.
>
> Exactly what does happen - a ValueError is raised because you're(*)
> passing self into the file.read() function, and that input is invalid
> input - specifically:
>
>      ValueError: I/O operation on closed file
>
> *where you actually means python, because when you call
> `your_instance.method()`, it works effectively like a call to
> `YourClass.method(your_instance)`

The new idiom
with open("myfile.dat") as f:
     data = f.read()

partially encapsulates operations on the opened file before the 
automatic close. It is true however, that after the with statement, f in 
still uselessly bound to the closed file. (Well, you can check the mode, 
encoding, and other attributes, so not totally useless.) To completely 
encapsulate, one can end the block with 'del f'. I checked and this 
works. Since the external 'as x' name binding is optional, an internal 
reference to the context manager (the io.xxx instance) is kept in order 
to call the __exit__ method, and that is not affected by deleting the 
optional visible binding.

tjr





More information about the Python-list mailing list