if session['dp'] := current_user.avatar :
^ SyntaxError: cannot use assignment expressions with subscript
Why Python forbids this use of walrus operator?
The error is a simple typo: x = 0, which assigns 0 to the variable x, was written while the comparison x == 0 is certainly what was intended.
Assignment expressions allow variable assignments to occur inside of larger expressions. While assignment expressions are never strictly necessary to write correct Python code, they can help make existing Python code more concise.
There is new syntax := that assigns values to variables as part of a larger expression. It is affectionately known as “the walrus operator” due to its resemblance to the eyes and tusks of a walrus.
The walrus operator creates an assignment expression. The operator allows us to assign a value to a variable inside a Python expression. It is a convenient operator which makes our code more compact. We can assign and print a variable in one go.
If you need to support older versions of Python, you can’t ship code that uses assignment expressions. There are some projects, like walrus, that can automatically translate walrus operators into code that is compatible with older versions of Python.
One of the main reasons assignments were not expressions in Python from the beginning is that the visual likeness of the assignment operator ( =) and the equality comparison operator ( ==) could potentially lead to bugs. When introducing assignment expressions, a lot of thought was put into how to avoid similar bugs with the walrus operator.
Instead, using assignment expressions where they are useful can help you make several small improvements to your code that could benefit your work overall. There are many times it’s possible for you to use the walrus operator, but where it won’t necessarily improve the readability or efficiency of your code.
In the examples you’ve seen so far, the := assignment expression operator does essentially the same job as the = assignment operator in your old code. You’ve seen how to simplify code, and now you’ll learn about a different type of use case that’s made possible by this new operator.
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;
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With