python-peps/peps/pep-0379.rst

197 lines
4.9 KiB
ReStructuredText
Raw Normal View History

2009-03-16 17:07:42 -04:00
PEP: 379
Title: Adding an Assignment Expression
Version: $Revision$
Last-Modified: $Date$
Author: Jervis Whitley <jervisau@gmail.com>
Status: Withdrawn
2009-03-16 17:07:42 -04:00
Type: Standards Track
2017-01-24 15:47:22 -05:00
Content-Type: text/x-rst
2009-03-16 17:07:42 -04:00
Created: 14-Mar-2009
2009-03-16 17:09:05 -04:00
Python-Version: 2.7, 3.2
2009-03-16 17:07:42 -04:00
Post-History:
Abstract
2017-01-24 15:47:22 -05:00
========
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
This PEP adds a new assignment expression to the Python language
to make it possible to assign the result of an expression in
almost any place. The new expression will allow the assignment of
the result of an expression at first use (in a comparison for
example).
2009-03-16 17:07:42 -04:00
Motivation and Summary
2017-01-24 15:47:22 -05:00
======================
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
Issue1714448 "if something as x:" [1]_ describes a feature to allow
assignment of the result of an expression in an if statement to a
name. It supposed that the ``as`` syntax could be borrowed for this
purpose. Many times it is not the expression itself that is
interesting, rather one of the terms that make up the
expression. To be clear, something like this::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
if (f_result() == [1, 2, 3]) as res:
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
seems awfully limited, when this::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
if (f_result() as res) == [1, 2, 3]:
is probably the desired result.
2009-03-16 17:07:42 -04:00
Use Cases
2017-01-24 15:47:22 -05:00
=========
See the Examples section near the end.
2009-03-16 17:07:42 -04:00
Specification
2017-01-24 15:47:22 -05:00
=============
A new expression is proposed with the (nominal) syntax::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
EXPR -> VAR
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
This single expression does the following:
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
- Evaluate the value of ``EXPR``, an arbitrary expression;
- Assign the result to ``VAR``, a single assignment target; and
- Leave the result of ``EXPR`` on the Top of Stack (TOS)
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
Here ``->`` or (``RARROW``) has been used to illustrate the concept that
the result of ``EXPR`` is assigned to ``VAR``.
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
The translation of the proposed syntax is::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
VAR = (EXPR)
(EXPR)
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
The assignment target can be either an attribute, a subscript or
name::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
f() -> name[0] # where 'name' exists previously.
2009-03-16 17:07:42 -04:00
f() -> name.attr # again 'name' exists prior to this expression.
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
f() -> name
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
This expression should be available anywhere that an expression is
currently accepted.
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
All exceptions that are currently raised during invalid
assignments will continue to be raised when using the assignment
expression. For example, a ``NameError`` will be raised when in
example 1 and 2 above if ``name`` is not previously defined, or an
``IndexError`` if index 0 was out of range.
2009-03-16 17:07:42 -04:00
Examples from the Standard Library
2017-01-24 15:47:22 -05:00
==================================
The following two examples were chosen after a brief search
through the standard library, specifically both are from ast.py
which happened to be open at the time of the search.
Original::
def walk(node):
from collections import deque
todo = deque([node])
while todo:
node = todo.popleft()
todo.extend(iter_child_nodes(node))
yield node
Using assignment expression::
def walk(node):
from collections import deque
todo = deque([node])
while todo:
todo.extend(iter_child_nodes(todo.popleft() -> node))
yield node
Original::
def get_docstring(node, clean=True):
if not isinstance(node, (FunctionDef, ClassDef, Module)):
raise TypeError("%r can't have docstrings"
% node.__class__.__name__)
if node.body and isinstance(node.body[0], Expr) and \
isinstance(node.body[0].value, Str):
if clean:
import inspect
return inspect.cleandoc(node.body[0].value.s)
return node.body[0].value.s
Using assignment expression::
def get_docstring(node, clean=True):
if not isinstance(node, (FunctionDef, ClassDef, Module)):
raise TypeError("%r can't have docstrings"
% node.__class__.__name__)
if node.body -> body and isinstance(body[0] -> elem, Expr) and \
isinstance(elem.value -> value, Str):
if clean:
import inspect
return inspect.cleandoc(value.s)
return value.s
2009-03-16 17:07:42 -04:00
Examples
2017-01-24 15:47:22 -05:00
========
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
The examples shown below highlight some of the desirable features
of the assignment expression, and some of the possible corner
cases.
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
1. Assignment in an if statement for use later::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
def expensive():
import time; time.sleep(1)
return 'spam'
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
if expensive() -> res in ('spam', 'eggs'):
dosomething(res)
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
2. Assignment in a while loop clause::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
while len(expensive() -> res) == 4:
dosomething(res)
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
3. Keep the iterator object from the for loop::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
for ch in expensive() -> res:
sell_on_internet(res)
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
4. Corner case::
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
for ch -> please_dont in expensive():
pass
# who would want to do this? Not I.
2009-03-16 17:07:42 -04:00
References
2017-01-24 15:47:22 -05:00
==========
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
.. [1] Issue1714448 "if something as x:", k0wax
http://bugs.python.org/issue1714448
2009-03-16 17:07:42 -04:00
Copyright
2017-01-24 15:47:22 -05:00
=========
This document has been placed in the public domain.
2009-03-16 17:07:42 -04:00
2017-01-24 15:47:22 -05:00
..
Local Variables:
mode: indented-text
indent-tabs-mode: nil
sentence-end-double-space: t
fill-column: 70
coding: utf-8
End: