[Final] PEP 3135 - New Super

원문 링크: PEP 3135 - New Super

상태: Final 유형: Standards Track 작성일: 28-Apr-2007

PEP 3135 – 새로운 super()

개요

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

제안된 새로운 super 사용법은 다음과 같습니다.

super().foo(1, 2)

이는 기존의 다음 코드를 대체합니다.

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

도입 배경 (Rationale)

기존의 super 사용법은 super가 작동해야 하는 클래스와 인스턴스를 명시적으로 전달해야 했습니다. 이는 DRY(Don’t Repeat Yourself) 원칙을 위반하며, 클래스 이름이 변경될 경우 코드 수정이 필요하여 많은 개발자에게 “옥에 티”로 여겨져 왔습니다.

명세 (Specification)

새로운 super 의미 체계는 Python 3.0부터만 사용 가능합니다.

기존의 super 사용법을 대체하며, 이제 명시적으로 클래스 객체를 전달하지 않고도 MRO(Method Resolution Order)에서 다음 클래스의 메서드를 호출할 수 있습니다 (물론 명시적 전달도 여전히 지원됩니다).

모든 함수는 해당 함수가 정의된 클래스 객체를 포함하는 __class__라는 셀(cell)을 가지게 됩니다.

새로운 구문인 super()는 다음 코드와 동등합니다.

super(__class__, <firstarg>)

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

super는 예약어(reserved word)는 아니지만, 파서(parser)는 메서드 정의 내에서 super의 사용을 인식하고 이 경우에만 __class__ 셀을 전달합니다. 따라서 인자 없이 super의 전역 별칭을 호출하는 것은 작동하지 않을 수 있습니다.

해결된 문제 (Closed Issues)

  • 사용할 클래스 객체 결정: 클래스 객체는 __class__라는 셀에서 가져옵니다.
  • super를 예약어로 만들어야 하는가?: 아닙니다. super가 예약어가 될 필요는 없습니다.
  • super__call__ 속성 사용: super 인스턴스를 기존 방식으로 인스턴스화할 때 __call__ 속성을 조회하여 MRO의 다음 클래스로 자동 super 조회를 시도할 수 있다는 우려가 있었으나, 객체 호출은 객체의 타입에서 직접 __call__ 메서드를 조회하므로 사실이 아님이 밝혀졌습니다. 또한, super(<class>, <instance>)와 같은 기존 super 호출은 여전히 동일한 의미로 지원되므로 이 문제는 완전히 사라집니다.

대안 제안 (Alternative Proposals)

  • 변경 없음 (No Changes): 현 상태를 유지하는 것이 매력적일 수 있지만, super 사용법 변경에 대한 요구가 오랫동안 있었으며, 이는 정당한 이유(클래스 이름으로부터의 분리, 더 간결하고 깔끔한 super 호출)에서 비롯되었습니다.
  • super 타입의 동적 속성 (Dynamic attribute on super type): super 타입에 동적 속성 조회를 추가하여 적절한 클래스 및 인스턴스 매개변수를 자동으로 결정하는 제안입니다. 이 제안은 sys._getframe()에 의존하며, 이는 프로토타입 구현을 제외하고는 적절하지 않습니다.
  • self.__super__.foo(*args): __super__ 속성은 이 PEP의 여러 곳에서 언급되며, 완전한 해결책의 후보가 될 수 있지만, __로 시작하는 이름은 일반적으로 내부적인 세부 사항이며 일상적인 코드에서는 사용을 지양합니다.
  • super(self, *args) 또는 __super__(self, *args): 이 해결책은 타입 표기 문제만 해결하며, 이름이 다른 super 메서드를 처리하지 않고 인스턴스 이름을 명시해야 합니다.
  • super.foo(self, *args): 이 방식은 적절한 인스턴스를 찾는 문제를 해결합니다.
  • super(*p, **kw): super(*p, **kw)를 직접 호출하는 것이 현재 실행 중인 메서드와 동일한 이름의 메서드를 super 객체에서 호출하는 것과 동등하다는 제안이 있었습니다. 하지만 이에 대한 찬반 의견이 강하고 구현 및 스타일 문제가 명확합니다. 귀도 반 로섬(Guido van Rossum)은 KISS(Keep It Simple Stupid) 원칙에 따라 이 제안을 이 PEP에서 제외해야 한다고 제안했습니다.

⚠️ 알림: 이 문서는 AI를 활용하여 번역되었으며, 기술적 정확성을 보장하지 않습니다. 정확한 내용은 반드시 원문을 확인하시기 바랍니다.

Comments