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

Python 개선 제안 한국어 번역

PEP 3130 – 현재 모듈/클래스/함수에 대한 접근

Author:
Jim J. Jewett <jimjjewett at gmail.com>
Status:
Rejected
Type:
Standards Track
Created:
22-Apr-2007
Python-Version:
3.0
Post-History:
22-Apr-2007

Table of Contents

번역·라이선스 안내

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

거부 공지

이 PEP는 거부되었습니다. 이 기능을 어떻게 구현해야 하는지, 경계 사례에서 정확한 의미론이 어떠해야 하는지가 명확하지 않으며, 제시된 중요한 사용 사례도 충분하지 않습니다. 반응도 기껏해야 미지근한 수준이었습니다.

초록

현재 모듈, 클래스 또는 함수에 대한 참조가 필요한 경우는 흔하지만, 현재로서는 이를 완전히 올바르게 수행할 방법이 없습니다. 이 PEP는 __module__, __class__, __function__ 키워드를 추가할 것을 제안합니다.

__module__의 근거

많은 모듈은 다양한 함수, 클래스 및 기타 객체를 내보내지만, 스크립트로 실행될 때는 (단위 테스트 실행과 같은) 추가 작업을 수행합니다. 현재의 관용구는 모듈의 이름이 매직 값으로 설정되었는지를 검사하는 것입니다.

if __name__ == "__main__": ...

더 복잡한 인트로스펙션을 하려면 모듈이 자기 자신을 임포트해야(임포트를 시도해야) 합니다. 예상한 이름을 임포트했는데 실제로는 다른 모듈이 나온다면, 마땅한 우회 방법이 없습니다.

# __import__ lets you use a variable, but... it gets more
# complicated if the module is in a package.
__import__(__name__)

# So just go to sys modules... and hope that the module wasn't
# hidden/removed (perhaps for security), that __name__ wasn't
# changed, and definitely hope that no other module with the
# same name is now available.
class X(object):
    pass

import sys
mod = sys.modules[__name__]
mod = sys.modules[X.__class__.__module__]

제안: 현재 정의(실행)되고 있는 모듈을 가리키는 __module__ 키워드를 추가합니다. (단, 미해결 문제를 참조하십시오.)

# XXX sys.main is still changing as draft progresses.  May
# really need sys.modules[sys.main]
if __module__ is sys.main:    # assumes PEP (3122), Cannon
    ...

__class__의 근거

클래스의 메서드에는 현재 인스턴스가 전달되며, 이로부터 self.__class__ (클래스 메서드의 경우 cls)를 알아낼 수 있습니다. 안타깝게도 이 참조는 객체의 실제 클래스를 가리키며, 이는 메서드를 정의한 클래스의 서브클래스일 수 있습니다. 현재의 우회 방법은 클래스의 이름을 반복해서 쓰고, 그 이름이 다시 바인딩되지 않으리라고 가정하는 것입니다.

class C(B):

    def meth(self):
        super(C, self).meth() # Hope C is never rebound.

class D(C):

    def meth(self):
        # ?!? issubclass(D,C), so it "works":
        super(C, self).meth()

제안: 현재 정의(실행)되고 있는 클래스를 가리키는 __class__ 키워드를 추가합니다. (단, 미해결 문제를 참조하십시오.)

class C(B):
    def meth(self):
        super(__class__, self).meth()

super 호출은 “New Super” PEP(Spealman)에 의해 더욱 단순해질 수 있다는 점에 유의하십시오. __class__ (또는 __this_class__) 속성은 그 PEP의 설명 및/또는 구현을 단순화하려는 시도 중에 제기되었지만, 별개의 독립적인 결정 사항으로 분리되었습니다.

__class__ (또는 __this_class__)는 바인딩된 super 객체의 __thisclass__ 프로퍼티와 완전히 같지는 않다는 점에 유의하십시오. 기존의 super.__thisclass__ 프로퍼티는 메서드 결정 순서(Method Resolution Order) 탐색이 시작되는 클래스를 가리킵니다. 위의 클래스 D에서라면, 이 프로퍼티는 C(라는 이름이 현재 참조하는 대상)를 가리킬 것입니다.

__function__의 근거

함수(메서드 포함)는 흔히 자기 자신에 접근하고자 하며, 이는 대개 전용 저장 공간이나 진정한 재귀를 위해서입니다. 몇 가지 우회 방법이 있지만, 모두 저마다 단점이 있습니다.

def counter(_total=[0]):
    # _total shouldn't really appear in the
    # signature at all; the list wrapping and
    # [0] unwrapping obscure the code
    _total[0] += 1
    return _total[0]

@annotate(total=0)
def counter():
    # Assume name counter is never rebound:
    counter.total += 1
    return counter.total

# class exists only to provide storage:
class _wrap(object):

    __total = 0

    def f(self):
        self.__total += 1
        return self.__total

# set module attribute to a bound method:
accum = _wrap().f

# This function calls "factorial", which should be itself --
# but the same programming styles that use heavy recursion
# often have a greater willingness to rebind function names.
def factorial(n):
    return (n * factorial(n-1) if n else 1)

제안: 현재 정의(실행)되고 있는 함수(또는 메서드)를 가리키는 __function__ 키워드를 추가합니다. (단, 미해결 문제를 참조하십시오.)

@annotate(total=0)
def counter():
    # Always refers to this function obj:
    __function__.total += 1
    return __function__.total

def factorial(n):
    return (n * __function__(n-1) if n else 1)

하위 호환성

사용자가 이미 이 이름들을 사용하고 있을 수도 있지만, 이중 밑줄 이름( __anything__ )은 명시적으로 인터프리터용으로 예약되어 있습니다. 따라서 단일 기능 릴리스 안에서 이 이름들에 특별한 의미를 도입하는 것은 허용됩니다.

구현

이상적으로는 이 이름들이 바이트코드 컴파일러가 특별하게 취급하는 키워드가 되어야 합니다.

Guido는 메타클래스가 채워 넣는 셀 변수를 사용하자고 제안했습니다 [1].

Michele Simionato는 바이트코드 해킹을 사용한 프로토타입을 제공했습니다 [2]. 이 방식은 새로운 바이트코드 연산자를 전혀 필요로 하지 않으며, 기존 연산자 중 어떤 특정 순서의 연산자가 실행되는지만 바꿉니다.

미해결 문제

  • __module__, __class__, __function__이 적절한 이름입니까? 특히 이름에 “this”라는 단어를 포함해야 합니까? 포함한다면 __this_module__, __this_class__, __this_function__처럼 할 수도 있고(python-3000 및 python-ideas 메일링 리스트에서 논의된 형식), __thismodule__, __thisclass__, __thisfunction__처럼 할 수도 있습니다(현재 super.``__thisclass__``의 용법에서 착안했지만 그 용법과 충돌합니다).
  • 세 키워드가 모두 필요합니까, 아니면 이 개선 사항을 일부 객체로만 한정해야 합니까? 메서드를 다른 함수와 별도로 취급해야 합니까?

참고 문헌