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

Python 개선 제안 한국어 번역

PEP 379 – 대입 표현식 추가하기

Author:
Jervis Whitley <jervisau at gmail.com>
Status:
Withdrawn
Type:
Standards Track
Created:
14-Mar-2009
Python-Version:
2.7, 3.2
Post-History:


Table of Contents

번역·라이선스 안내

이 비공식 한국어 번역은 원문 Copyright 절의 Public Domain 조건에 따라 제공합니다. 원저자와 공식 원문은 그대로 표시합니다. 수정되지 않은 기준 원문 · 공식 최신판

초록

이 PEP는 거의 모든 위치에서 표현식의 결과를 대입할 수 있도록 Python 언어에 새로운 대입 표현식을 추가합니다. 새 표현식은 (예를 들어 비교에서) 처음 사용할 때 표현식의 결과를 대입할 수 있게 해줍니다.

동기와 요약

Issue1714448 “if something as x:” [1] 은 if 문에서 표현식의 결과를 이름에 대입할 수 있게 하는 기능을 기술합니다. 이는 이 목적을 위해 as 구문을 차용할 수 있다고 가정했습니다. 흥미로운 것은 표현식 자체가 아니라 표현식을 구성하는 항 중 하나인 경우가 많습니다. 명확히 하자면, 다음과 같은 것은:

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

다음이 아마도 원하는 결과일 때:

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

지나치게 제한적으로 보입니다.

사용 사례

끝부분의 예제 절을 참조하십시오.

명세

(임시로) 다음 구문을 가진 새로운 표현식이 제안됩니다:

EXPR -> VAR

이 단일 표현식은 다음을 수행합니다:

  • 임의의 표현식인 EXPR의 값을 평가합니다.
  • 그 결과를 단일 할당 대상인 VAR에 할당합니다. 그리고
  • EXPR의 결과를 스택 최상단(TOS)에 남깁니다.

여기서 -> 또는 (RARROW)는 EXPR의 결과가 VAR에 할당된다는 개념을 나타내기 위해 사용되었습니다.

제안된 구문을 옮기면 다음과 같습니다.:

VAR = (EXPR)
(EXPR)

할당 대상은 어트리뷰트, 서브스크립트, 또는 이름 중 하나일 수 있습니다.:

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

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

f() -> name

이 표현식은 현재 표현식이 허용되는 모든 위치에서 사용할 수 있어야 합니다.

잘못된 할당 시 현재 발생하는 모든 예외는 할당 표현식을 사용할 때도 계속 발생합니다. 예를 들어, 위의 예제 1과 2에서 name이 이전에 정의되지 않았다면 NameError가 발생하며, 인덱스 0이 범위를 벗어났다면 IndexError가 발생합니다.

표준 라이브러리의 예제

다음 두 예제는 표준 라이브러리를 간단히 검색한 후 선택한 것으로, 특히 검색 당시 마침 열려 있던 ast.py에서 가져온 것입니다.

원본:

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

할당 표현식을 사용한 경우:

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

원본:

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

할당 표현식을 사용한 경우:

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

예제

아래 예제들은 할당 표현식의 바람직한 특징 몇 가지와 발생 가능한 몇 가지 코너 케이스를 보여줍니다.

  1. 이후 사용을 위해 if 문에서 할당하기:
    def expensive():
        import time; time.sleep(1)
        return 'spam'
    
    if expensive() -> res in ('spam', 'eggs'):
        dosomething(res)
    
  2. while 루프 절에서 할당하기:
    while len(expensive() -> res) == 4:
        dosomething(res)
    
  3. for 루프의 이터레이터 객체 유지하기:
    for ch in expensive() -> res:
        sell_on_internet(res)
    
  4. 코너 케이스:
    for ch -> please_dont in expensive():
        pass
    # who would want to do this? Not I.
    

참고 자료