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

Python 개선 제안 한국어 번역

PEP 366 – 메인 모듈의 명시적 상대 임포트

Author:
Alyssa Coghlan <ncoghlan at gmail.com>
Status:
Final
Type:
Standards Track
Created:
01-May-2007
Python-Version:
2.6, 3.0
Post-History:
01-May-2007, 04-Jul-2007, 07-Jul-2007, 23-Nov-2007

Table of Contents

번역·라이선스 안내

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

초록

이 PEP는 패키지 내 실행 가능 모듈에서 명시적 상대 임포트를 사용할 수 있도록 허용하는, 하위 호환되는 메커니즘을 제안합니다. 이러한 임포트는 현재 PEP 328PEP 338사이의 어색한 상호작용으로 인해 실패합니다.

새로운 모듈 수준 속성을 추가함으로써, 이 PEP는 모듈이 -m 스위치를 사용하여 실행되는 경우 상대 임포트가 자동으로 작동하도록 허용합니다. 모듈 자체에 소량의 보일러플레이트를 추가하면 파일이 이름으로 실행될 때 상대 임포트가 작동하도록 할 수 있습니다.

귀도는 2007년 11월에 이 PEP를 승인했습니다 [5].

제안된 변경

주요 제안 변경 사항은 새로운 모듈 수준 속성인 __package__의 도입입니다. 이 속성이 존재하면, 상대 임포트는 모듈의 __name__ 속성이 아니라 이 속성을 기반으로 이루어집니다.

현재의 __name__ 속성과 마찬가지로, __package__를 설정하는 것은 모듈을 임포트하는 데 사용되는 PEP 302 로더의 책임입니다. imp.new_module()을 사용하여 모듈 객체를 생성하는 로더는 새 속성이 자동으로 None으로 설정됩니다. 임포트 시스템이 __package__가 설정되지 않은(또는 None으로 설정된) 모듈에서 명시적 상대 임포트를 발견하면, 올바른 값(일반 모듈의 경우 __name__.rpartition('.')[0], 패키지 초기화 모듈의 경우 __name__)을 계산하여 저장합니다. __package__가 이미 설정되어 있다면 임포트 시스템은 __name____path__ 속성으로부터 패키지 이름을 다시 계산하는 대신 이를 우선적으로 사용합니다.

runpy 모듈은 모듈의 __name__ 속성을 설정하는 데 사용된 이름이 아니라, 실행할 모듈을 찾는 데 사용된 이름을 기반으로 새 속성을 명시적으로 설정합니다. 이를 통해 -m 스위치로 실행된 메인 모듈에서 상대 임포트가 올바르게 작동할 수 있습니다.

메인 모듈이 파일명으로 지정된 경우, __package__ 속성은 None으로 설정됩니다. 모듈이 직접 실행될 때 상대 임포트를 허용하려면, 첫 번째 상대 임포트 문 앞에 다음과 유사한 보일러플레이트가 필요합니다:

if __name__ == "__main__" and __package__ is None:
    __package__ = "expected.package.name"

이 보일러플레이트는 최상위 패키지가 이미 sys.path를 통해 접근 가능한 경우에만 충분하다는 점에 유의하십시오. 최상위 패키지가 아직 임포트 가능하지 않은 상태에서 직접 실행이 작동하도록 하려면, sys.path를 조작하는 추가 코드가 필요합니다.

이 접근 방식은 형제 모듈의 절대 임포트를 사용하는 것과 동일한 단점을 가지고 있습니다 - 스크립트가 다른 패키지나 하위 패키지로 이동하면, 보일러플레이트를 수동으로 갱신해야 합니다. 상대 임포트의 개수와 관계없이 파일당 한 번만 이 변경을 수행하면 된다는 장점이 있습니다.

__package__를 명시적으로 빈 문자열로 설정하는 것도 허용되며, 이 경우 해당 모듈로부터의 모든 상대 임포트를 비활성화하는 효과가 있다는 점에 유의하십시오(이 경우 임포트 기계는 해당 모듈을 최상위 모듈로 간주하기 때문입니다). 이는 runpy와 같은 도구가 __package__를 설정할 때 최상위 모듈에 대한 특수 사례 처리를 제공할 필요가 없음을 의미합니다.

변경 근거

메인 모듈에서 명시적 상대 임포트를 사용할 수 없는 현재의 문제는 적어도 하나의 열려 있는 SF 버그 리포트(#1510172) [1]의 주제이며, comp.lang.python에서의 적어도 몇몇 질의(가령 [2]의 Alan Isaac의 질문)에 있어서도 하나의 요인이었을 가능성이 큽니다.

이 PEP는 인터프리터 시작이나 일반적인 모듈 임포트 과정에서 어떠한 유의미한 비용도 발생시키지 않으면서, 메인 모듈에서 명시적 상대 임포트를 허용하는 해법을 제공하고자 합니다.

상대 임포트와 메인 모듈을 다루는 PEP 338의 절에서는 이 문제에 대한 추가 세부 정보와 배경을 제공합니다.

참조 구현

SVN의 리비전 47142는 메인 모듈의 실제 모듈 이름을 __module_name__ 속성에 저장하는 이 제안의 초기 변형을 구현했습니다. 그 당시 2.5가 이미 베타 단계에 있었다는 사실로 인해 이는 되돌려졌습니다.

패치 1487 [4]이 이 PEP의 제안된 구현입니다.

대안 제안

PEP 3122는 메인 모듈을 식별하는 방식을 변경하여 이 문제를 해결하자고 제안했습니다. 이는 전체적인 관점에서 보면 상당히 사소한 버그를 고치기 위해 감수하기에는 큰 하위 호환성 비용이며, 해당 PEP는 거부되었습니다 [3].

이 PEP에서 제안하는 방식의 장점은 일반적인 코드에 미치는 영향이 모듈을 임포트할 때 추가 속성을 설정하는 데 필요한 약간의 시간뿐이라는 점입니다. 패키지 이름이 모듈 전역 변수에 캐시되어 매번 상대 임포트마다 다시 계산할 필요가 없으므로, 상대 임포트 자체도 미세하게 빨라질 것입니다.

참고 자료