object.enable() anti-pattern

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu May 9 01:23:59 EDT 2013


On Thu, 09 May 2013 02:42:01 +0000, Dan Sommers wrote:

> On Wed, 08 May 2013 08:52:12 +0000, Steven D'Aprano wrote:
> 
>> This is an anti-pattern to avoid. The idea is that creating a resource
>> ought to be the same as "turning it on", or enabling it, or similar.
>> For example, we don't do this in Python:
>> 
>> f = file("some_file.txt")
>> f.open()
>> data = f.read()
> 
> So why don't we do this?
> 
>     data = read("some_file.txt")

Because there is a lot more that you might want to do to a file than just 
read from it.

py> f = open('/tmp/x')
py> dir(f)
['_CHUNK_SIZE', '__class__', '__delattr__', '__dict__', '__dir__', 
'__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', 
'__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', 
'__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', 
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '_checkClosed', '_checkReadable', 
'_checkSeekable', '_checkWritable', 'buffer', 'close', 'closed', 
'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 
'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 
'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 
'writable', 'write', 'writelines']


That's 24 public methods and attributes, excluding private and dunder 
attributes.

There is no sensible use-case for creating a file without opening it. 
What would be the point? Any subsequent calls to just about any method 
will fail. Since you have to open the file after creating the file object 
anyway, why make them two different calls?

Besides, this is not to denigrate the idea of a read() function that 
takes a filename and returns its contents. But that is not an object 
constructor. It may construct a file object internally, but it doesn't 
return the file object, so it is completely unrelated to the scenario I 
described.



>> because reading the file can fail if you forget to call open first.
>> Instead, Python uses a factory function that creates the file object
>> and opens it:
>> 
>> f = open("some_file.txt")  # if this succeeds, f is ready to use 
>> data = f.read()
> 
> That's just the "enable" paradigm in a socially acceptable and
> traditional wrapper.

Well duh. That's like saying that for loops, while loops and co-routines 
are just GOTO in a socially acceptable and traditional wrapper. Of course 
they are. That's the whole point.



-- 
Steven



More information about the Python-list mailing list