Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 379 – Hinzufügen eines Zuweisungsausdrucks

Autor:
Jervis Whitley <jervisau at gmail.com>
Status:
Zurückgezogen
Typ:
Standards Track
Erstellt:
14. Mrz 2009
Python-Version:
2.7, 3.2
Post-History:


Inhaltsverzeichnis

Zusammenfassung

Dieses PEP fügt der Python-Sprache einen neuen Zuweisungsausdruck hinzu, um die Zuweisung des Ergebnisses eines Ausdrucks fast überall zu ermöglichen. Der neue Ausdruck wird die Zuweisung des Ergebnisses eines Ausdrucks bei der ersten Verwendung (z. B. in einem Vergleich) ermöglichen.

Motivation und Zusammenfassung

Issue1714448 „if something as x:“ [1] beschreibt eine Funktion, die die Zuweisung des Ergebnisses eines Ausdrucks in einer if-Anweisung an einen Namen erlaubt. Es wurde angenommen, dass die as-Syntax zu diesem Zweck verwendet werden könnte. Oft ist nicht der Ausdruck selbst interessant, sondern einer der Begriffe, aus denen sich der Ausdruck zusammensetzt. Um es klar zu sagen, so etwas wie dieses

if (f_result() == [1, 2, 3]) as res:

scheint sehr begrenzt, wenn dies

if (f_result() as res) == [1, 2, 3]:

wahrscheinlich das gewünschte Ergebnis ist.

Anwendungsfälle

Siehe den Abschnitt Beispiele am Ende.

Spezifikation

Es wird ein neuer Ausdruck mit der (nominalen) Syntax vorgeschlagen

EXPR -> VAR

Dieser einzelne Ausdruck tut Folgendes

  • Wertet den Wert von EXPR, einem beliebigen Ausdruck, aus;
  • Weist das Ergebnis VAR, einem einzelnen Zuweisungsziel, zu; und
  • Lässt das Ergebnis von EXPR auf dem obersten Stapel (TOS) liegen.

Hier wurde -> oder (RARROW) verwendet, um das Konzept zu illustrieren, dass das Ergebnis von EXPR VAR zugewiesen wird.

Die Übersetzung der vorgeschlagenen Syntax lautet

VAR = (EXPR)
(EXPR)

Das Zuweisungsziel kann ein Attribut, ein Subskript oder ein Name sein.

f() -> name[0]      # where 'name' exists previously.

f() -> name.attr    # again 'name' exists prior to this expression.

f() -> name

Dieser Ausdruck sollte überall dort verfügbar sein, wo derzeit ein Ausdruck akzeptiert wird.

Alle Ausnahmen, die derzeit bei ungültigen Zuweisungen ausgelöst werden, werden auch bei Verwendung des Zuweisungsausdrucks weiterhin ausgelöst. Zum Beispiel wird ein NameError in Beispiel 1 und 2 oben ausgelöst, wenn name nicht zuvor definiert wurde, oder ein IndexError, wenn Index 0 außerhalb des Bereichs lag.

Beispiele aus der Standardbibliothek

Die folgenden beiden Beispiele wurden nach einer kurzen Suche in der Standardbibliothek ausgewählt, beide stammen speziell aus ast.py, das zum Zeitpunkt der Suche geöffnet war.

Original

def walk(node):
    from collections import deque
    todo = deque([node])
    while todo:
        node = todo.popleft()
        todo.extend(iter_child_nodes(node))
        yield node

Verwendung des Zuweisungsausdrucks

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

Verwendung des Zuweisungsausdrucks

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

Beispiele

Die unten gezeigten Beispiele heben einige der wünschenswerten Merkmale des Zuweisungsausdrucks und einige mögliche Eckfälle hervor.

  1. Zuweisung in einer if-Anweisung zur späteren Verwendung
    def expensive():
        import time; time.sleep(1)
        return 'spam'
    
    if expensive() -> res in ('spam', 'eggs'):
        dosomething(res)
    
  2. Zuweisung in einer while-Schleifenklausel
    while len(expensive() -> res) == 4:
        dosomething(res)
    
  3. Behalten des Iterator-Objekts aus der for-Schleife
    for ch in expensive() -> res:
        sell_on_internet(res)
    
  4. Eckfall
    for ch -> please_dont in expensive():
        pass
    # who would want to do this? Not I.
    

Referenzen


Quelle: https://github.com/python/peps/blob/main/peps/pep-0379.rst

Zuletzt geändert: 2025-02-01 08:59:27 GMT