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

Python 개선 제안 한국어 번역

PEP 3152 – 코함수

Author:
Gregory Ewing <greg.ewing at canterbury.ac.nz>
Status:
Rejected
Type:
Standards Track
Created:
13-Feb-2009
Python-Version:
3.3
Post-History:


Table of Contents

번역·라이선스 안내

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

초록

‘코함수’라고 하는 특수한 유형의 제너레이터를 정의하고 호출하기 위한 구문을 제안합니다. 이는 제너레이터 기반 코루틴을 간결하게 작성하는 방법을 제공하고, 이러한 코드를 작성할 때 쉽게 발생하지만 진단하기 어려운 증상을 일으키는 특정 종류의 오류를 조기에 감지할 수 있도록 설계되었습니다.

이 제안은 PEP 380에 설명된 ‘yield from’ 메커니즘을 기반으로 하며, 코함수의 일부 의미론을 이를 바탕으로 설명합니다. 그러나 원한다면 PEP 380과 독립적으로 코함수를 정의하고 구현하는 것도 가능합니다.

거부

https://mail.python.org/pipermail/python-dev/2015-April/139503.html 을 참조하십시오.

사양

코함수 정의

코함수를 정의하기 위해 def대신 사용하는 새로운 키워드 codef를 도입합니다. 코함수는 다음 특성을 갖는 특수한 종류의 제너레이터입니다.

  1. 코함수는 yield 또는 yield from 표현식을 포함하지 않더라도 항상 제너레이터입니다.
  2. 코함수는 일반 함수와 같은 방식으로 호출할 수 없습니다. 코함수를 일반적으로 호출하려고 하면 예외가 발생합니다.

코호출

한 코함수에서 다른 코함수로 호출할 때는 새로운 키워드 cocall로 호출을 표시합니다. 다음 표현식은

cocall f(*args, **kwds)

의미상 다음과 동등합니다.

yield from f.__cocall__(*args, **kwds)

단, __cocall__이 반환하는 객체는 이터레이터일 것으로 예상되므로 해당 객체에 대해 iter()를 호출하는 단계는 생략합니다.

코호출 표현식의 전체 구문은 다음 문법 규칙으로 설명합니다.:

atom: cocall | <existing alternatives for atom>
cocall: 'cocall' atom cotrailer* '(' [arglist] ')'
cotrailer: '[' subscriptlist ']' | '.' NAME

cocall키워드는 코함수 내부에서만 구문적으로 유효합니다. 다른 컨텍스트에서 사용하면 SyntaxError가 발생합니다.

__cocall__을 구현하는 객체는 이터레이터 프로토콜을 준수하는 객체를 반환할 것으로 예상됩니다. 코함수는 일반 제너레이터 함수가 __call__에 응답하는 것과 동일한 방식으로 __cocall__에 응답합니다. 즉, 제너레이터-이터레이터를 반환합니다.

다른 호출 가능 객체를 감싸는 특정 객체, 특히 바운드 메서드에는 기반 객체에 처리를 위임하는 __cocall__ 구현이 제공됩니다.

새로운 내장 함수, 속성 및 C API 함수

코함수와 비코루틴 코드를 쉽게 연결할 수 있도록 costart라는 내장 함수가 제공되며, 그 정의는 다음과 동등합니다.

def costart(obj, *args, **kwds):
    return obj.__cocall__(*args, **kwds)

이에 대응하는 C API 함수도 제공됩니다.

PyObject *PyObject_CoCall(PyObject *obj, PyObject *args, PyObject *kwds)

현재로서는 코함수가 별개의 객체 유형인지, 아니면 제너레이터 함수처럼 단순히 특별히 표시된 함수 인스턴스인지 명시하지 않습니다. 후자의 경우, 주어진 함수 객체가 코함수인지 검사할 수 있도록 읽기 전용 불리언 속성 __iscofunction__을 제공해야 합니다.

동기와 근거

yield from구문은 제너레이터 작업의 일부를 다른 함수에 위임하는 목적으로 사용할 경우 상당히 직관적입니다. 또한 제너레이터 기반 코루틴의 구현에 효과적으로 사용할 수 있지만, 그 목적으로 사용하면 다소 어색하게 읽히며 코드의 진정한 의도를 가리는 경향이 있습니다.

또한 제너레이터를 코루틴으로 사용하는 것은 다소 오류가 발생하기 쉽습니다. yield from을 사용해야 할 때 사용하는 것을 잊거나, 사용하지 말아야 할 때 사용하면 그 결과로 나타나는 증상이 모호하고 혼란스러울 수 있습니다.

마지막으로, 아무것도 yield하지 않더라도 함수가 코루틴이어야 하는 경우가 있으며, 이러한 경우에는 함수를 제너레이터로 만들기 위해 if 0: yield와 같은 편법을 사용해야 합니다.

codefcocall 구문은 구문이 의도를 직접 반영하도록 하여 첫 번째 문제를 해결합니다. 즉, 해당 함수가 코루틴의 일부를 이룬다는 의도를 반영합니다.

두 번째 문제는 의미가 통하지 않는 방식으로 코루틴 코드와 비코루틴 코드를 혼합할 수 없게 함으로써 해결합니다. 규칙을 위반하면 무엇이 어디에서 문제인지 정확히 지적하는 예외가 발생합니다.

마지막으로, 함수에 무엇이 들어 있는지가 아니라 정의 형식에 따라 해당 함수가 코루틴인지 결정하도록 하여 더미 yield가 필요하지 않게 합니다.

프로토타입 구현

Python 3.1.2용 패치 형태의 구현은 다음에서 찾을 수 있습니다:

http://www.cosc.canterbury.ac.nz/greg.ewing/python/generators/cofunctions.html