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__ 속성은 메서드 결정 순서 검색이 시작되는 클래스를 가리킵니다. 위의 클래스 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__``에서 영감을 받았지만 충돌하는 형식)으로 해야 합니까?- 세 키워드가 모두 필요합니까, 아니면 이 개선 사항을 객체의 일부로 제한해야 합니까? 메서드를 다른 함수와 별도로 처리해야 합니까?
참고 문헌
Copyright
This document has been placed in the public domain.