TL;DR:
expr except (default if exc_expr) expr (except default if exc_expr) expr except (exc_expr: default) expr (except exc_expr: default) (1) Group the exceptions with the default they imply. (2) inline-":" still needs () or [] or {}. (3) Consider the expression inside a longer line. (3a) Does the except expression need to be general, or would it work if it were limited to a subclause of variable assignments? (3b) What about comprehensions? On Fri Mar 7 20:54:31 CET 2014, Chris Angelico wrote: >On Sat, Mar 8, 2014 at 5:58 AM, Jim J. Jewett <jimjjewett at gmail.com> wrote: >> (Thu Mar 6 23:26:47 CET 2014) Chris Angelico responded: >>> On Fri, Mar 7, 2014 at 7:29 AM, Jim J. Jewett <jimjjewett at gmail.com> >>> wrote: >>>> [ note that "x if y" already occurs in multiple contexts, and >>>> always evaluates y before x. ] ... > I don't see except expressions as fundamentally more associated with > if/else than with, say, an or chain, which works left to right. I do, because of the skipping portion. Short-circuiting operators, such as an "or" chain, never skip a clause unless they are skipping *every* subsequent clause. An "if" statement sometimes skips the (unlabeled in python) "then" clause, but still processes the even-later "else" clause. A "try" statement sometimes skips the remainder of the try suite but still executes the later subordinate "except" and "finally" clauses. Note that this only explains why I see "except" as more closely related to "if" than to "or"; it isn't sufficient to justify going back to execute the skipped clause later. That said, going back to a previous location is a lot easier to excuse after an error handler than in "regular" code. > Analysis of the Python standard library suggests that the single-if > situation is *by far* the most common, to the extent that it'd hardly > impact the stdlib at all to add multiple except clauses to the > proposal. Do you have a strong use-case for the more full syntax? I do not. I dislike the arbitrary restriction, and I worry that lifting it later (while maintaining backwards compatibility) will result in a syntax wart, but I do not have a compelling use case for that later relaxation. >> and I strongly prefer that they [the parentheses] be internal >> (which you fear looks too much like calling a function named except). >> In that case, it is: >> expr1 except (expr3 if expr2) > I'm still not really seeing how this is better. For one thing, it makes it clear that the "if" keyword may be messing with the order of evaluation. I don't claim that syntax is perfect. I do think it is less flawed than the no-parentheses (or external parentheses) versions: (expr1 except expr3 if expr2) expr1 except expr3 if expr2 because the tigher parentheses correctly indicate that expr2 and expr3 should be considered as a (what-to-do-in-case-of-error) group, which interacts (as a single unit) with the main expression. I also think it is (very slighly) better than the colon+internal-parentheses version: expr1 except (expr2: expr3) which in turn is far, far better than the colon versions with external or missing parentheses: (expr1 except expr2: expr3) expr1 except expr2: expr3 because I cannot imagine reading an embedded version of either of those without having to mentally re-parse at the colon. An example assuming a precedence level that may not be what the PEP proposes: if myfunc(5, expr1 except expr2: expr3, "label"): for i in range(3, 3*max(data) except TypeError: 9, 3): ... if myfunc(5, (expr1 except expr2: expr3), "label"): for i in range(3, (3*max(data) except TypeError: 9), 3): ... if myfunc(5, expr1 except (expr2: expr3), "label"): for i in range(3, 3*max(data) except (TypeError: 9), 3): ... if myfunc(5, expr1 except (expr2: expr3), "label"): for i in range(3, 3*max(data) (except TypeError: 9), 3): ... if myfunc(5, expr1 except (expr3 if expr3), "label"): for i in range(3, 3*max(data) (except 9 if TypeError), 3): ... if myfunc(5, expr1 except (expr3 if expr3), "label"): for i in range(3, 3*max(data) except (9 if TypeError), 3): myarg = expr1 except (expr3 if expr2) if myfunc(5, myarg, "label"): limit = 3*max(data) except (9 if TypeError) for i in range(3, limit, 3): Yes, I would prefer to create a variable naming those expressions, but these are all still simple enough that I would expect to have to read them. (I like constructions that get ugly just a bit faster than they get hard to understand.) If I have to parse any of them, the ones at the bottom are less difficult than the ones at the top. > With the colon version, it looks very much like dict display, which is good, since that is one of the acceptable uses of inline-colon. > only with different brackets around it; in some fonts, that'll be > very easily confused. I've had more trouble with comma vs period than with different types of bracket. But let's assume that there is confusion, and someone sees: expr1 except [expr2:expr3] or expr1 except {expr2:expr3} These are not yet defined any more than the tuple-with-colon version is, nor do they have an obvious-yet-incompatible meaning. In fact, I would prefer either of them to any version that does not syntactically associate the exception list with the result those exceptions imply. >> The other three inline uses (dict display, slide notation, and >> function parameter annotation) are effectively conjunction operators, >> saying that expr1 and expr2 are bound more tightly than you would >> assume if they were separated by commas. They only occur inside >> a fairly close bracket (of some sort), and if the bracket isn't >> *very* close, then there are usually multiple associates-colons >> inside the same bracket. > Not sure that really helps. This isn't going to be as tight as a > slice, and it's most often not going to have multiple colons inside > the brackets. The colon is acceptable only to the extent that this similarity does help. So if a colon is used, I want the similarity to be as strong as possible -- which, I suppose, is another argument for tightening the parentheses, and possibly an argument for using [] instead of (). -jJ -- If there are still threading problems with my replies, please email me with details, so that I can try to resolve them. -jJ _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com