[Python-ideas] With expressions

Steven D'Aprano steve at pearwood.info
Sat Aug 4 03:32:22 EDT 2018


On Sat, Aug 04, 2018 at 12:40:13AM +0200, Benedikt Werner wrote:

> Overall I like the idea of the with-expression as it allows you to make 
> some common use cases like the open/read example more readable. 

For some definition of "readable".

> It's 
> clear at first sight that what is actually done is reading the file.

Only because the file.read() comes early in the expression. But that 
applies equally to 

    text = read('filename')


> While it's true that it's usually easy to write a simple function to do 
> the job that still isn't as simple to understand 


(1) read(filename)

Explanation to a beginner:

"It reads text from the named file."


(2) f.read() with open(filename) as f

Explanation to a beginner:

"It opens a file -- I'll explain what it means to open a file 
later -- in a context manager -- that's advanced Python programming, 
don't worry about context managers for now -- and binds the context 
manager to the name f, then calls the read method on the object f -- 
I'll explain object oriented programming later -- which reads text from 
the named file and closes the file... oh I forgot to mention that the 
context manager is also a file object."

Do you still think that explaining a with expression is simpler than 
explaining a self-descriptively named function?


The beauty of the named function is that it hides a lot of irrelevant 
detail and focuses *only* on the important feature, which is reading 
from the file.

A with-statement is great for when you care about the 
implementation details. Somebody has to care about the process of 
opening a file, reading from it and closing it. But when you *don't* 
care about those implementation details, a simple interface like a 
read() function is superior to a with-statement, *or* a with-expression, 
which shoves those details in your face.


> and in most cases when 
> reading the code you then have to look at the function to see if 
> anything else is done there.

I doubt that many people really spend a lot of time digging into 
functions to see whether they do more than what they say. Unless and 
until I ran into unexpected problems, I'd be no more inclined to look 
into a function called "read" than I would be to do the same to len or 
math.sin. I'm sure it does what it says it does.

In Python 2, one of the problems with the input() function was that it 
was used by people who didn't read the docs and where taken completely 
by surprise by the fact that it called eval on the input. That shows 
that people don't make a habit of digging into functions "just in case".


> Also what if you then do readlines 
> somewhere? Then you need another function.

Indeed. But not everything has to be a built-in feature, and refactoring 
common code into a named function will often be a good idea *even if* 
``with`` is an exception:

def read(filename, size=-1, **kwargs):
    return f.read(size) with open(filename, **kwargs) as f


-- 
Steve


More information about the Python-ideas mailing list