Permalink
Cannot retrieve contributors at this time
196 lines (136 sloc)
4.92 KB
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
peps/pep-0379.txt
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| PEP: 379 | |
| Title: Adding an Assignment Expression | |
| Version: $Revision$ | |
| Last-Modified: $Date$ | |
| Author: Jervis Whitley <jervisau@gmail.com> | |
| Status: Withdrawn | |
| Type: Standards Track | |
| Content-Type: text/x-rst | |
| Created: 14-Mar-2009 | |
| Python-Version: 2.7, 3.2 | |
| Post-History: | |
| Abstract | |
| ======== | |
| 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). | |
| Motivation and Summary | |
| ====================== | |
| 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:: | |
| if (f_result() == [1, 2, 3]) as res: | |
| seems awfully limited, when this:: | |
| if (f_result() as res) == [1, 2, 3]: | |
| is probably the desired result. | |
| Use Cases | |
| ========= | |
| See the Examples section near the end. | |
| Specification | |
| ============= | |
| A new expression is proposed with the (nominal) syntax:: | |
| EXPR -> VAR | |
| This single expression does the following: | |
| - 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) | |
| Here ``->`` or (``RARROW``) has been used to illustrate the concept that | |
| the result of ``EXPR`` is assigned to ``VAR``. | |
| The translation of the proposed syntax is:: | |
| VAR = (EXPR) | |
| (EXPR) | |
| The assignment target can be either an attribute, a subscript or | |
| name:: | |
| f() -> name[0] # where 'name' exists previously. | |
| f() -> name.attr # again 'name' exists prior to this expression. | |
| f() -> name | |
| This expression should be available anywhere that an expression is | |
| currently accepted. | |
| 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. | |
| Examples from the Standard Library | |
| ================================== | |
| 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 | |
| Examples | |
| ======== | |
| The examples shown below highlight some of the desirable features | |
| of the assignment expression, and some of the possible corner | |
| cases. | |
| 1. Assignment in an if statement for use later:: | |
| def expensive(): | |
| import time; time.sleep(1) | |
| return 'spam' | |
| if expensive() -> res in ('spam', 'eggs'): | |
| dosomething(res) | |
| 2. Assignment in a while loop clause:: | |
| while len(expensive() -> res) == 4: | |
| dosomething(res) | |
| 3. Keep the iterator object from the for loop:: | |
| for ch in expensive() -> res: | |
| sell_on_internet(res) | |
| 4. Corner case:: | |
| for ch -> please_dont in expensive(): | |
| pass | |
| # who would want to do this? Not I. | |
| References | |
| ========== | |
| .. [1] Issue1714448 "if something as x:", k0wax | |
| http://bugs.python.org/issue1714448 | |
| Copyright | |
| ========= | |
| This document has been placed in the public domain. | |
| .. | |
| Local Variables: | |
| mode: indented-text | |
| indent-tabs-mode: nil | |
| sentence-end-double-space: t | |
| fill-column: 70 | |
| coding: utf-8 | |
| End: |