7
if session['dp'] := current_user.avatar :
    ^ SyntaxError: cannot use assignment expressions with subscript

Why Python forbids this use of walrus operator?

Smart Manoj
  • 3,837
  • 2
  • 24
  • 45
  • 1
    Not an exact duplicate, but the same issue occurs with attribute assignment, and that's discussed here: https://stackoverflow.com/a/59019790/ . There's no definitive answer to the "why" of it—just that the PEP designed it that way, and some speculation that that was to "avoid things getting too complicated," i.e. to limit the negative impact on code readability. – jez Mar 29 '20 at 01:07

2 Answers2

9

Because, as the alternative name (named expressions) suggests, the left hand side of the walrus operator is to be a NAME. Therefore, by definition such expressions as noted in your question as well as, for instance, function calls are not allowed to be assigned in this form.

The documentation also specifies:

Single assignment targets other than a single NAME are not supported

To further this argument, one can notice that cPython explicitly checks if the expression is Name_kind:

if (target->kind != Name_kind) {
    const char *expr_name = get_expr_name(target);
    if (expr_name != NULL) {
        ast_error(c, n, "cannot use assignment expressions with %s", expr_name);
    }
    return NULL;
}
Arn
  • 1,708
  • 8
  • 22
  • 1
    This answers to 'technical why' - because 'they said so'. But why they said so? I think this is because there is ambiguous meaning for `if` statement: what is correct `if session['dp']:` or `if sesson:`. And to eliminate this ambiguity they deny assignments to anything except plain variable name. – Alexey Ruzin Jan 26 '21 at 09:30
  • @AlexeyRuzin that wouldn't be ambiguous since the value of the assignement expression is the value of the right hand side. In this case it would be `current_user.avatar` – TitouanT Mar 13 '21 at 15:54
  • You are right. Have you an idea, why it is not possible though? – Alexey Ruzin Mar 14 '21 at 19:53
3

There is some justification for the decision to disallow more complex assignments in assignment expressions given on the python-dev mailing list.

In particular, from Chris Angelico:

Assignment to arbitrary targets would also mean permitting iterable unpacking, which is not desired ("x, y := 3, 4"??), and there weren't enough use-cases for attribute/item assignment to justify creating a rule of "you can assign to any single target, but can't unpack". In the future, if such use-cases are found, the grammar can be expanded.

-- https://mail.python.org/pipermail/python-dev/2018-July/154628.html

and from Guido himself:

Also nobody had a use case.

-- https://mail.python.org/pipermail/python-dev/2018-July/154631.html

That's probably as close to an explanation as is possible. Presumably if there's demand the feature may be expanded in some future version.

khelwood
  • 46,621
  • 12
  • 59
  • 83
  • 2
    +1 for providing a rationale answer. Making small modifications to numpy arrays or pandas dataframes is a fairly large use-case in any kind of data work that may have been overlooked at the time. It is likely worth revisiting. – Axoren May 06 '21 at 20:00