25.10.21 21:26, jcg.stu...@gmail.com пише:
> I've been thinking for a while that it would be good to be able to use 
> context managers in an expression context, and I haven't been able to come up 
> with any arguments against it (although it may not be to everyone's taste) 
> and I can't see any sign that it's come up before (although the words of it 
> don't make very specific search terms).
> My suggestion is that a "with" clause could be written after an expression 
> (consistent with the conditional operator being written with "if" after the 
> first expression).
> 
> In general, this would be:
>   a(b) with c(d) as b
> or it could allow multiple context managers:
>   a(b, c) with d(e) as b, f(g) as c
> 
> My original motivating example was this:
> 
> if name.startswith("https://";):
>     data = requests.get(name).json()
> else:
>     with open(name) as stream:
>         data = json.load(stream)
> 
> which I'd much rather be able to write with a single expression:
> 
> data = (requests.get(name).json()
>         if name.startswith("https://";)
>         else (json.load(stream)
>               with open(name) as stream))
> 
> It would behave just like a "with" statement, but pass a value / values back.

I was going to propose this idea for discussion but did not have enough
time to formulate it.

It is not just a "what if we combine two random features idea", it would
cover most cases of recurrent requests for adding functions which merge
open() and json.load(), etc or adding new very specialized methods to
the Path object. Currently you can write

    with open(filename, 'rb') as f:
        data = json.load(f)

The only minor drawback of this idiom is that it is not expression (but
you always can write a new function). If you could write

    data = json.load(f) with open(filename, 'rb') as f

this counter-argument will disappear.

Now, Mark Gordon asked a good question -- what to do if the context
manager suppresses an exception. We do not have value and we do not have
exception. The only answer I have -- raise a RuntimeError (or other
specialized exception). It should be an error to use context managers
which suppress exceptions in the "with" expression. Maybe there are
better ideas.

Before adding the "with" expressions we should consider other feature:
the "with" clause in comprehensions.

Currently comprehensions can contain "for" and "if" clauses. There
should be at least one "for" clause and it should be the first clause. I
propose to add the with clause. It will be interpreted the same way as
"if" and nested "for" clauses. [expr for x in iterable if cond() with
cm() as y] should be equivalent to:

    result = []
    for x in iterable:
        if cond():
            with cm() as y:
                result.append(expr)

It should be discussed because there is a conflict between its syntax
and the "with" expression. The "with" clause should have priority over
the "with" expression (as the "if" clause has priority over the "if"
expression), but it is a breaking change if the latter will be
implemented first.

_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/5QGMJWY7UGLEIKCXMIHMIM7ZLVCLJ646/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to