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

Python 개선 제안 한국어 번역

PEP 3135 – 새로운 Super

Author:
Calvin Spealman <ironfroggy at gmail.com>, Tim Delaney <timothy.c.delaney at gmail.com>, Lie Ryan <lie.1296 at gmail.com>
Status:
Final
Type:
Standards Track
Created:
28-Apr-2007
Python-Version:
3.0
Post-History:
28-Apr-2007, 29-Apr-2007, 29-Apr-2007, 14-May-2007, 12-Mar-2009

Table of Contents

번역·라이선스 안내

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

번호 매기기 참고 사항

이 PEP는 PEP 367로 시작되었습니다. 이제 Python 3000을 대상으로 하므로 3xxx 영역으로 이동되었습니다.

초록

이 PEP는 super 타입을 사용하여 메서드가 정의된 클래스와 메서드가 현재 작동하는 인스턴스(또는 클래스 메서드의 경우 클래스 객체)에 바인딩되는 super 타입의 인스턴스를 자동으로 생성하기 위한 구문 설탕을 제안합니다.

제안된 새로운 super 사용법의 전제는 다음과 같습니다.:

super().foo(1, 2)

기존 방식을 대체하기 위해:

super(Foo, self).foo(1, 2)

근거

현재 super 사용법은 작동 대상이 되는 클래스와 인스턴스를 모두 명시적으로 전달해야 하므로 DRY(Don’t Repeat Yourself) 규칙을 위반하게 됩니다. 이는 클래스 이름을 변경하는 데 방해가 되며, 많은 사람이 이를 흔히 결함으로 여깁니다.

명세

명세 절에서는 서로 비슷하고 밀접하게 관련된 개념을 구별하기 위해 몇 가지 특수 용어를 사용합니다. “super class”는 “super”라는 이름의 실제 내장 클래스를 가리킵니다. “super instance”는 단순히 super 클래스의 인스턴스이며, 다른 클래스 및 경우에 따라 해당 클래스의 인스턴스와 연결됩니다.

새로운 super 의미론은 Python 3.0에서만 사용할 수 있습니다.

기존 super 사용법을 대체하면 클래스 객체를 명시적으로 전달하지 않고도 MRO(메서드 결정 순서)의 다음 클래스에 호출을 수행할 수 있습니다(물론 명시적으로 전달하는 방식도 계속 지원됩니다). 모든 함수에는 해당 함수가 정의된 클래스 객체를 포함하는 __class__라는 셀이 있습니다.

새로운 구문은:

super()

다음과 동등합니다.:

super(__class__, <firstarg>)

여기서 __class__는 메서드가 정의된 클래스이고, <firstarg>는 메서드의 첫 번째 매개변수입니다(일반적으로 인스턴스 메서드에서는 self, 클래스 메서드에서는 cls입니다). 클래스 본문 외부에서 정의된 함수에는 __class__가 정의되지 않으며, 런타임에 SystemError가 발생합니다.

super는 예약어가 아니지만, 파서는 메서드 정의에서 super가 사용된 것을 인식하고 이 경우에만 __class__ 셀을 전달합니다. 따라서 인수 없이 super의 전역 별칭을 호출하는 방식이 반드시 작동하지는 않습니다.

해결된 문제

사용할 클래스 객체 결정

클래스 객체는 __class__라는 셀에서 가져옵니다.

super가 실제로 키워드가 되어야 하는가?

아니요. super가 키워드가 될 필요는 없습니다.

__call__ 속성과 함께 사용되는 super

super 인스턴스를 고전적인 방식으로 인스턴스화하면 호출 시 __call__ 속성을 검색하여 MRO의 다음 클래스에 자동으로 super 검색을 수행하려 할 수 있으므로 문제가 될 수 있다고 여겨졌습니다. 그러나 객체를 호출할 때는 해당 객체의 타입에서 직접 __call__ 메서드만 검색하므로 이는 사실이 아닌 것으로 밝혀졌습니다. 다음 예제가 이를 보여 줍니다.

class A(object):
    def __call__(self):
        return '__call__'
    def __getattribute__(self, attr):
        if attr == '__call__':
            return lambda: '__getattribute__'
a = A()
assert a() == '__call__'
assert a.__call__() == '__getattribute__'

어쨌든 super(<class>, <instance>)에 대한 기존 호출이 동일한 의미로 계속 지원되므로 이 문제는 완전히 사라집니다.

대안 제안

변경 없음

모든 것을 현재 방식 그대로 유지하는 것이 언제나 매력적으로 보이기는 하지만, 사람들은 이전에 언급한 모든 이유로 한동안 super 호출 사용 방식의 변경을 요구해 왔습니다.

  • 클래스 이름과의 분리(더 이상 올바른 클래스에 바인딩되어 있지 않을 수도 있습니다!)
  • 더 단순하고 깔끔해 보이는 super 호출이 더 낫습니다.

super 타입의 동적 속성

이 제안은 super 타입에 동적 속성 조회를 추가하며, 이를 통해 적절한 클래스 및 인스턴스 매개변수를 자동으로 결정합니다. 각 super 속성 조회는 이러한 매개변수를 식별하고 인스턴스에서 super 조회를 수행하며, 이는 현재 super 구현이 클래스와 인스턴스에 대해 super 인스턴스를 명시적으로 호출할 때 수행하는 방식과 같습니다.

이 제안은 sys._getframe()에 의존하며, 프로토타입 구현 이외의 용도에는 적절하지 않습니다.

self.__super__.foo(*args)

__super__ 속성은 이 PEP의 여러 곳에서 언급되며, super를 직접 사용하는 대신 실제로 이를 명시적으로 사용하는 완전한 해결책의 후보가 될 수 있습니다. 그러나 이중 밑줄 이름은 대개 내부 세부 사항이며, 일상적인 코드에서 사용되지 않도록 유지하려고 합니다.

super(self, *args) 또는 __super__(self, *args)

이 해결책은 타입 표시 문제만 해결하며, 이름이 서로 다른 super 메서드는 처리하지 않고 인스턴스 이름을 명시합니다. 필요한 경우 다른 메서드 이름에도 적용할 수 없으므로, 유연성이 떨어집니다. 이 해결책이 실패하는 한 가지 사용 사례는 베이스 클래스에 팩토리 클래스 메서드가 있고 서브클래스에 두 개의 팩토리 클래스 메서드가 있는 경우이며, 두 메서드 모두 베이스 클래스의 메서드를 적절히 호출해야 합니다.

super.foo(self, *args)

이 변형은 실제로 적절한 인스턴스를 찾는 문제를 없애며, 대안 중 하나라도 주목받게 된다면 저는 이것이 되기를 바랍니다.

super(*p, **kw)

super(*p, **kw)를 직접 호출하면 현재 실행 중인 메서드와 동일한 이름을 가진 super 객체의 메서드를 호출하는 것과 같아진다는 제안이 있었습니다. 즉, 다음 두 메서드는 동일해집니다.

def f(self, *p, **kw):
    super.f(*p, **kw)
def f(self, *p, **kw):
    super(*p, **kw)

이에 대한 찬반 의견은 강하지만, 구현 및 스타일상의 우려도 분명합니다. Guido는 KISS(Keep It Simple Stupid) 원칙에 따라 이를 이 PEP에서 제외해야 한다고 제안했습니다.

역사

2007년 4월 29일
  • 제목을 “Super As A Keyword”에서 “New Super”로 변경했습니다.
  • 혼동하기 쉬운 부분을 명확히 하기 위해 언어의 상당 부분을 업데이트하고 용어 섹션을 추가했습니다.
  • 참조 구현 및 역사 섹션을 추가했습니다.
2007년 5월 6일
  • python-3000 및 python-dev 메일링 리스트에서의 논의를 반영하도록 Tim Delaney가 업데이트했습니다.
2009년 3월 12일
  • 현재 구현 상태를 반영하도록 업데이트했습니다.

참고 문헌

[1] super를 수정할 사람? (https://mail.python.org/pipermail/python-3000/2007-April/006667.html)

[2] PEP 3130: 현재 정의 중인 모듈/클래스/함수에 대한 접근(this) (https://mail.python.org/pipermail/python-ideas/2007-April/000542.html)