Makes sense. However, couldn't you prevent that by giving with priority over the binding ? As in "(with simple_cm) as value", where we consider the "as" as binding operator instead of part of the with statement ? Sure, you could commit suicide by parenthesis, but by default it'd do exactly what the "with simple_cm as value" currently does. This does require use of as instead of :=, though. (which was the point I was trying to make, apologies for the confusion)
Does "(with simple_cm) as value" means "with (simple_cm as value)"? If so, it's impossible to let the priority of "with ... as ..." over `as` binding.
This is the grammar of current syntax related to with statement:
with_stmt: 'with' with_item (',' with_item)* ':' suite with_item: test ['as' expr]
If `as` binding could be used in a general expression, just as `test` is the top of expression, an expression using `as` binding must be in the structure > `test`. In other words, if you write
with expr as name: # do stuff
Without doubt it's equivalent to `with (expr as name)`.
Or you want to completely change the grammar design of CPython :)
thautwarm
Additionally, here is an evidence.
I've just had a look at Chris Angelico's implementation about expression
assignment, it's cool, however the problem is still raised.
https://github.com/Rosuav/cpython/blob/0f237048b7665720b5165a40de0ed601c1e82...
`as` binding is added at line 111, obviously you cannot separate it from
the `test` structure(because `test` is the top expr).
testlist_comp: (test|star_expr) ( comp_for | 'as' NAME | (','
(test|star_expr))* [','] )
It seems that if we're to support expression assignment, `as` binding
should be declined.
To be honest I feel upset because I think `expr as name` is really cool and
pythonic.
thautwarm
2018-04-13 1:35 GMT+08:00 Thautwarm Zhao
Makes sense. However, couldn't you prevent that by giving with priority over the binding ? As in "(with simple_cm) as value", where we consider the "as" as binding operator instead of part of the with statement ? Sure, you could commit suicide by parenthesis, but by default it'd do exactly what the "with simple_cm as value" currently does. This does require use of as instead of :=, though. (which was the point I was trying to make, apologies for the confusion)
Does "(with simple_cm) as value" means "with (simple_cm as value)"? If so, it's impossible to let the priority of "with ... as ..." over `as` binding.
This is the grammar of current syntax related to with statement:
with_stmt: 'with' with_item (',' with_item)* ':' suite with_item: test ['as' expr]
If `as` binding could be used in a general expression, just as `test` is the top of expression, an expression using `as` binding must be in the structure `test`. In other words, if you write
with expr as name: # do stuff
Without doubt it's equivalent to `with (expr as name)`.
Or you want to completely change the grammar design of CPython :)
thautwarm
2018-04-12 21:41 GMT+08:00
: Send Python-ideas mailing list submissions to python-ideas@python.org
To subscribe or unsubscribe via the World Wide Web, visit https://mail.python.org/mailman/listinfo/python-ideas or, via email, send a message with subject or body 'help' to python-ideas-request@python.org
You can reach the person managing the list at python-ideas-owner@python.org
When replying, please edit your Subject line so it is more specific than "Re: Contents of Python-ideas digest..."
Today's Topics:
1. Re: PEP 572: Assignment Expressions (post #4) (Chris Angelico) 2. Re: PEP 572: Assignment Expressions (post #4) (Chris Angelico) 3. Re: PEP 572: Assignment Expressions (post #4) (Nick Coghlan) 4. Re: PEP 572: Assignment Expressions (post #4) (Jacco van Dorp) 5. Re: PEP 572: Assignment Expressions (post #4) (Chris Angelico)
---------- 已转发邮件 ---------- From: Chris Angelico
To: python-ideas Cc: Bcc: Date: Thu, 12 Apr 2018 23:08:06 +1000 Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4) On Thu, Apr 12, 2018 at 9:09 PM, Paul Moore wrote: On 11 April 2018 at 22:28, Chris Angelico
wrote: On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan
wrote: This argument will be strengthened by making the examples used in the PEP itself more attractive, as well as proposing suitable additions to PEP 8, such as:
1. If either assignment statements or assignment expressions can be used, prefer statements 2. If using assignment expressions would lead to ambiguity about execution order, restructure to use statements instead
Fair enough. Also adding that chained assignment expressions should generally be avoided.
Another one I think should be included (I'm a bit sad that it's not so obvious that no-one would ever even think of it, but the current discussion pretty much killed that hope for me).
* Assignment expressions should never be used standalone - assignment statements should *always* be used in that case.
That's covered by the first point. If it's a standalone statement, then the statement form could be used, ergo you should prefer the statement form.
ChrisA
---------- 已转发邮件 ---------- From: Chris Angelico
To: python-ideas Cc: Bcc: Date: Thu, 12 Apr 2018 23:14:34 +1000 Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4) On Thu, Apr 12, 2018 at 7:21 PM, Kirill Balunov wrote: I gain readability! I don't see any reason to use it in other
contexts...
Because it makes the code unreadable and difficult to perceive while giving not so much benefit. I may be wrong, but so far I have not seen a single example that at least slightly changed my mind.
This is, in effect, your entire argument for permitting assignments only in certain contexts. "I can't think of any useful reason for doing this, so we shouldn't do it". But that means making the language grammar more complicated (both in the technical sense of the parser's definitions, and in the colloquial sense of how you'd explain Python to a new programmer), because there are these magic constructs that can be used anywhere in an expression, but ONLY if that expression is inside an if or while statement. You lose the ability to refactor your code simply to satisfy an arbitrary restriction to appease someone's feeling of "it can't be useful anywhere else".
There are basically two clean ways to do this:
1) Create actual syntax as part of the while statement, in the same way that the 'with EXPR as NAME:' statement does. This means you cannot put any additional operators after the 'as NAME' part. It's as much a part of the statement's syntax as the word 'in' is in a for loop.
2) Make this a feature of expressions in general. Then they can be used anywhere that an expression can be.
I've gone for option 2. If you want to push for option 1, go ahead, but it's a nerfed solution just because you personally cannot think of any good use for this.
ChrisA
---------- 已转发邮件 ---------- From: Nick Coghlan
To: Chris Angelico Cc: python-ideas Bcc: Date: Thu, 12 Apr 2018 23:19:59 +1000 Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4) On 12 April 2018 at 07:28, Chris Angelico wrote: On Thu, Apr 12, 2018 at 1:22 AM, Nick Coghlan
wrote: Frequently Raised Objections ============================
There needs to be a subsection here regarding the need to call `del` at class and module scope, just as there is for loop iteration variables at those scopes.
Hmm, I'm not sure I follow. Are you saying that this is an objection to assignment expressions, or an objection to them not being statement-local? If the latter, it's really more about "rejected alternative proposals".
It's both - accidentally polluting class and module namespaces is an argument against expression level assignments in general, and sublocal namespaces aimed to eliminate that downside.
Since feedback on the earlier versions of the PEP has moved sublocal namespaces into the "rejected due to excessive conceptual complexity" box, that means accidental namespace pollution comes back as a downside that the PEP should mention.
I don't think it needs to say much, just point out that they share the downside of regular for loops: if you use one at class or module scope, and don't want to export the name, you need to delete it explicitly.
Cheers, Nick.
-- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
---------- 已转发邮件 ---------- From: Jacco van Dorp
To: python-ideas Cc: Bcc: Date: Thu, 12 Apr 2018 15:31:59 +0200 Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4) 2018-04-12 15:02 GMT+02:00 Nick Coghlan : On 12 April 2018 at 22:22, Jacco van Dorp
wrote: I've looked through PEP 343, contextlib docs ( https://docs.python.org/3/library/contextlib.html ), and I couldn't find a single case where "with (y := f(x))" would be invalid.
Consider this custom context manager:
@contextmanager def simple_cm(): yield 42
Given that example, the following code:
with cm := simple_cm() as value: print(cm.func.__name__, value)
would print "'simple_cm 42", since the assignment expression would reference the context manager itself, while the with statement binds the yielded value.
Another relevant example would be `contextlib.closing`: that returns the passed in argument from __enter__, *not* self.
And that's why earlier versions of PEP 572 (which used the "EXPR as NAME" spelling) just flat out prohibited top level name binding expressions in with statements: "with (expr as name):" and "with expr as name:" were far too different semantically for the only syntactic difference to be a surrounding set of parentheses.
Cheers, Nick.
Makes sense. However, couldn't you prevent that by giving with priority over the binding ? As in "(with simple_cm) as value", where we consider the "as" as binding operator instead of part of the with statement ? Sure, you could commit suicide by parenthesis, but by default it'd do exactly what the "with simple_cm as value" currently does. This does require use of as instead of :=, though. (which was the point I was trying to make, apologies for the confusion)
---------- 已转发邮件 ---------- From: Chris Angelico
To: python-ideas Cc: Bcc: Date: Thu, 12 Apr 2018 23:41:49 +1000 Subject: Re: [Python-ideas] PEP 572: Assignment Expressions (post #4) On Thu, Apr 12, 2018 at 11:31 PM, Jacco van Dorp wrote: 2018-04-12 15:02 GMT+02:00 Nick Coghlan
: On 12 April 2018 at 22:22, Jacco van Dorp
wrote: I've looked through PEP 343, contextlib docs ( https://docs.python.org/3/library/contextlib.html ), and I couldn't find a single case where "with (y := f(x))" would be invalid.
Consider this custom context manager:
@contextmanager def simple_cm(): yield 42
Given that example, the following code:
with cm := simple_cm() as value: print(cm.func.__name__, value)
would print "'simple_cm 42", since the assignment expression would reference the context manager itself, while the with statement binds the yielded value.
Another relevant example would be `contextlib.closing`: that returns the passed in argument from __enter__, *not* self.
And that's why earlier versions of PEP 572 (which used the "EXPR as NAME" spelling) just flat out prohibited top level name binding expressions in with statements: "with (expr as name):" and "with expr as name:" were far too different semantically for the only syntactic difference to be a surrounding set of parentheses.
Cheers, Nick.
Makes sense. However, couldn't you prevent that by giving with priority over the binding ? As in "(with simple_cm) as value", where we consider the "as" as binding operator instead of part of the with statement ? Sure, you could commit suicide by parenthesis, but by default it'd do exactly what the "with simple_cm as value" currently does. This does require use of as instead of :=, though. (which was the point I was trying to make, apologies for the confusion)
If you want this to be a generic name-binding operation, then no; most objects cannot be used as context managers. You'll get an exception if you try to use "with 1 as x:", for instance.
As Nick mentioned, there are context managers that return something other than 'self', and for those, "with expr as name:" has an important meaning that cannot easily be captured with an assignment operator.
ChrisA
_______________________________________________ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas