[Python-ideas] if with as

Larry Hastings larry at hastings.org
Mon Mar 5 23:19:40 CET 2007


Sam wrote:
> except blocks don't set up a new scope to me.
> [...second code example deleted...]
> says the same thing about the with statement to me.
>   
(What version of Python are you using, a 2.6 build?  In 2.5 release, a 
file() is not a context manager, so 'with file() as f:' doesn't work.  
And in py3k the "except E, N" syntax is gone.)

First off, you are absolutely right, the "with" and "except" statements 
do not open new scopes.  I was wrong about that.

But PEP 3110, "Catching Exceptions In Python:, describes "except E as N" 
this way:

    try:
        try_body
    except E as N:
        except_body
    ...

      

    gets translated to (in Python 2.5 terms)

    try:
        try_body
    except E, N:
        try:
            except_body
        finally:
            N = None
            del N
    ...

    http://www.python.org/dev/peps/pep-3110/
      

So the intent for "except E as N" is that N does *not* outlive the 
"except" block.  And indeed that's what happens in my month-old Py3k.

Also, in your example "with file(...) as f:", outside the "with" block 
"f" evaluated as "<closed file 'C:/foo.txt', mode 'r' at 0x00B98800>".  
The file was closed because "with file(...) as f:" wasn't simply 
assigning the result of the "with" expression to f; it assigns to f the 
result of calling __enter__() on the with with expression's result.  It 
seems that post-Python 2.5 file.__enter__() returns the file.  This 
isn't a bad thing, but it's a little misleading as "with A as X" doesn't 
usually wind up with X containing the "result" of A.

So I can state: in Py3k, in both cases of "except E as N" and "with E as 
N", after the nested block has exited, N does not contain the direct 
result of E.


I guess I'm starting to disagree with sprinkling "as" into the syntax as 
the defacto inline assignment operator.  Quoting from PEP 343:

    So now the final hurdle was that the PEP 310 <http://www.python.org/dev/peps/pep-0310> syntax:

        with VAR = EXPR:
            BLOCK1

    would be deceptive, since VAR does *not* receive the value of
    EXPR.  Borrowing from PEP 340 <http://www.python.org/dev/peps/pep-0340>, it was an easy step to:

        with EXPR as VAR:
             BLOCK1

      

    http://www.python.org/dev/peps/pep-0343/

Clearly the original intent with "as" was that it was specifically *not* 
direct assignment.  Python added a *new keyword*, specifically because 
this was not direct inline assignment.  So I assert a Python programmer 
should not see "as" and think "= with the two sides swapped".


For my final trick, I will attempt to channel Guido.  (Which is spooky, 
as he hasn't even Crossed Over To The Other Side.)  Python was 
originally written in C, the poster child for inline assignment 
operators, so he was obviously familiar with the syntactic construct.  
But Python does *not* support inline assignment everywhere.  AFAIK it 
specifically has supports for it in one place: allowing multiple 
assignments at once.  This works:

    a = b = file(...)

But this does not:

    if a = expression:
        # hooray, expression worked
    else:
        # boo, expression failed

Since nobody likes to type, I'm sure people have requested inline 
assignment zillions of times before.  Since Python does not support it, 
I'm guessing Guido doesn't want it for some reason.  Perhaps it's to 
save programmers from the inevitable heartache of typing "if a = x" when 
they meant "if a == x" (or vice-versa); if so then that's a little 
surprising, considering the "consenting adults" design tenet, but at 
least "if E as N" would not have that problem.  If there was some other 
reason, then I bet "if E as N" doesn't address it.

Knock three times,


/larry/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20070305/13a8e42c/attachment.html>


More information about the Python-ideas mailing list