Python 모듈의 절대적 vs. 명시 적 상대적 가져 오기


85

Python 응용 프로그램에서 패키지를 가져 오는 선호하는 방법이 궁금합니다. 다음과 같은 패키지 구조가 있습니다.

project.app1.models
project.app1.views
project.app2.models

project.app1.views수입 project.app1.modelsproject.app2.models. 떠오르는 두 가지 방법이 있습니다.

절대 수입 :

import A.A
import A.B.B

또는 PEP 328을 사용하는 Python 2.5에 도입 된 명시 적 상대 가져 오기 사용 :

# explicit relative
from .. import A
from . import B

이것을 수행하는 가장 비단뱀적인 방법은 무엇입니까?


"명시 적 상대"예제는 구문 오류입니다. 상대 수입은 형식이어야합니다 from _ import ..., 그래서 당신의 예는 것 from .. import Afrom . import B
MestreLion

@MestreLion 좋은 캐치, 당신은 절대적으로 옳습니다! 내 질문을에서 import ..A로 업데이트 했습니다 from .. import A. 누군가가 발견 될 때까지 만 구년 걸렸다 놀라운)
다니엘 Hepper

답변:


52

절대 수입. PEP 8 :

패키지 내 수입에 대한 상대적 수입은 매우 권장되지 않습니다. 모든 가져 오기에 항상 절대 패키지 경로를 사용하십시오. PEP 328 [7]이 Python 2.5에서 완전히 구현 되었음에도 불구하고 명시 적 상대 가져 오기 스타일은 적극적으로 권장되지 않습니다. 절대 가져 오기는 더 이식 가능하고 일반적으로 더 읽기 쉽습니다.

명시 적 상대 가져 오기는 좋은 언어 기능이지만 (내 생각에) 절대 가져 오기만큼 명시 적이지는 않습니다. 더 읽기 쉬운 형식은 다음과 같습니다.

import A.A
import A.B.B

특히 여러 다른 네임 스페이스를 가져 오는 경우. 패키지 내에서 가져 오기를 포함하는 잘 작성된 프로젝트 / 튜토리얼을 보면 일반적으로이 스타일을 따릅니다.

좀 더 명확하게하기 위해 몇 번의 추가 키 입력은 다른 사람들 (그리고 아마도 당신)이 당신의 네임 스페이스를 알아 내려고 할 때 (특히 당신이 3.x로 마이그레이션하는 경우) 많은 시간을 절약 할 것입니다. 이름이 변경되었습니다).


@Rafe, "잘 작성된 프로젝트를 좀보세요 ..."어떤 제안이 있습니까?
denis

@Denis : Rietveld는 Guido van Rossum의 자체 프로젝트이므로보기에 좋은 장소라고 생각합니다 ( code.google.com/p/rietveld ). Python 표준 라이브러리는 그다지 훌륭하지 않으며 많은 코드가 규칙을 따르지 않습니다.
Rafe Kettler 2011 년

68
@Rafe : Guido에 따르면 PEP-8의 해당 부분은 구식입니다. mail.python.org/pipermail/python-dev/2010-October/104476.html
Brandon Rhodes

12
그 성명서는 더 이상 PEP-8에 전혀 없습니다. 이제 절대 수입이 권장되지만 상대적 수입이 허용 가능한 대안이라고 명시되어 있습니다.
dano

6
절대 가져 오기와 관련된 문제는 다른 패키지 내에서 패키지를 사용할 때입니다. 제 경우에는 git 하위 모듈로 존재합니다. 이 경우 최상위 패키지를 가져올 수 있지만이 패키지 아래의 모든 패키지는 절대 가져 오기가있는 자체 모듈을 찾지 못하기 때문에 가져올 수 없습니다. 이 최하위 수준에서 상대 가져 오기를 사용하면 모두 작동합니다.
davidA

122

Python 상대 가져 오기는 더 이상 권장되지 않지만이 경우 absolute_import를 사용하는 것이 좋습니다.

Guido 자신을 인용 한이 토론을 참조하십시오 .

"이것은 대부분 역사적이지 않습니까? 새로운 상대 가져 오기 구문이 구현되기 전까지는 상대 가져 오기에 여러 가지 문제가있었습니다. 단기 솔루션은 사용하지 않는 것이 좋습니다. 장기적인 솔루션은 명확한 구문을 구현하는 것이 었습니다. 이제는 반 권장을 철회 할 때입니다. 물론, 배 밖으로 나가지 않고-나는 여전히 습득 한 취향을 발견하지만 그 자리가 있습니다. "

OP 는 다음 과 같은 PEP 328 을 올바르게 연결합니다 .

몇 가지 사용 사례가 제시되었으며, 그 중 가장 중요한 것은 하위 패키지를 편집하지 않고도 큰 패키지의 구조를 재정렬 할 수 있다는 것입니다. 또한 패키지 내부의 모듈은 상대적 가져 오기 없이는 쉽게 가져올 수 없습니다.

또한 거의 중복되는 질문을 참조하십시오. 언제 또는 왜 파이썬에서 상대 가져 오기를 사용하는지

물론 그것은 여전히 ​​맛의 문제입니다. 상대적인 가져 오기로 코드를 이동하는 것이 더 쉽지만 예기치 않게 문제가 발생할 수도 있습니다. 수입품의 이름을 바꾸는 것은 그리 어렵지 않습니다.

PEP 328에서 새로운 동작을 강제하려면 다음을 사용하십시오.

from __future__ import absolute_import

이 경우 암시 적 상대 가져 오기가 더 이상 가능하지 않습니다 (예 : import localfile더 이상 작동하지 않고 from . import localfile). 깨끗하고 미래의 증명 동작을 위해 absolute_import를 사용하는 것이 좋습니다.

중요한주의 사항은 PEP 338PEP 366 때문에 상대 가져 오기에는 python 파일을 모듈로 가져와야한다는 것 ValueError: Attempted relative import in non-package입니다. 상대 가져 오기가있는 file.py를 실행할 수 없거나 .

이 제한은 최상의 접근 방식을 평가할 때 고려되어야합니다. Guido는 어떤 경우에도 모듈에서 스크립트 실행에 반대합니다.

나는 이것과 __main__ 기계의 다른 제안 된 트위들 링에 대해 -1입니다. 유일한 유스 케이스는 모듈의 디렉토리 안에있는 스크립트를 실행하는 것 같습니다. 저는 항상 안티 패턴으로 보았습니다. 내가 내 마음을 바꾸게하려면 그렇지 않다고 나를 설득해야합니다.

이 문제에 대한 철저한 토론은 SO에서 찾을 수 있습니다. 레. Python 3는 매우 포괄적입니다.


9
귀도는 2010 년에 그것을 썼고 여전히 PEP에 있습니까? PEP가 너무 오래된 경우 어떻게 신뢰할 수 있습니까?
Jabba 2014 년

2
PEP는 수정이 가능하다는 점에서 미국의 수정과 같습니다. 거부 된 PEPS도 많이 있습니다. PEP는 제안입니다. 수락, 거부 또는 폐기 될 수 있으며 이는 종종 새로운 PEP를 의미합니다. PEP 8은 스타일 가이드이므로 제자리에서 수정할 수 있습니다.
CppLearner 2014 년

2
"패키지 내의 모듈은 쉽게 가져올 수 없습니다 ..."부분에 대해 혼란 스럽습니다. 나는 자기 자신을 가져 오는 모듈에 대해 들어 본 적이 없다.
matiascelasco 2014

2
한 가지 가능한 예 @matiascelasco : foo / bar.py 및 foo / baz.py가 있지만 다른 곳에 baz.py도있는 경우. bar에서 foo.baz를 가져 오려면 무엇을 가져 오는지 확인하고 싶을 수 있습니다. import .baz-이것은 PEP에 설명 된 많은 유사한 상황 중 하나 일뿐입니다.
Stefano

당신의 대답은 그들을 허용하는 변화를 명확하게 구별하지 못합니다. 암시 적 상대 가져 오기는 절대 사용해서는 안되지만 명시 적 상대 가져 오기는 사용할 수 있습니다. 암시 적 상대가 Python3에서 제거되었습니다.
ninMonkey 2015 년

33

상대 가져 오기를 사용하면 수십 개의 내부 가져 오기를 변경하지 않고 나중에 패키지 이름을 자유롭게 변경할 수있을뿐만 아니라 순환 가져 오기 또는 네임 스페이스 패키지와 같은 특정 문제를 해결하는 데 성공했습니다. top "을 눌러 최상위 네임 스페이스에서 다시 다음 모듈 검색을 시작합니다.


4
이것은 Python 스타일 가이드에 따르면 권장되지 않는 스타일입니다. 가독성이 심하게 흐려지고 당신이 언급하는 "편의성"에 대한 가치가 없습니다. 문제를 해결하기 위해 상대 가져 오기를 사용해야한다면 잘못하고있는 것입니다.
Rafe Kettler

14
다른 답변에 대한 그의 (Brandon Rhodes) 의견에 더 이상 낙담하지 않음을 보여주는 링크가 있습니다.
Jon Coombs 2014 년

1
@RafeKettler는 다른 패키지에 포함 된 패키지에서 절대 가져 오기를 사용하는 방법을 설명 할 수 있습니까? 절대 가져 오기는 새로운 최상위 수준에 대해 모르기 때문에 내부 패키지 내에서 실패합니다. 상대적 수입은 계속 작동합니다. 처음에는 패키지가 다른 패키지 안에 중첩되어서는 안된다고 주장 할 수 있지만 일부 코드는 재사용이 가능하며 이런 일이 많이 발생합니다. 재사용 된 많은 코드가 대중을 위해 패키징되지 않으므로 별도의 패키지로 제공되지 않으므로 VCS 가져 오기 / 하위 모듈과 같은 임시 메서드가 대신 사용됩니다
davidA

3
@meowsqueak 동의합니다. 일부 패키지는 쉽게 설치할 수 없습니다 (pip에 있지 않고 사용하고 싶지 python setup.py install않거나 python setup.py develop어떤 이유로 든).이 경우 소스 코드를 포크하고 git 하위 모듈로 추가합니다. 해당 패키지가 자체 패키지 이름에 절대 가져 오기를 사용하면 가져 오기가 실패합니다. 유일한 해결책은 명시 적 상대 가져 오기를 사용하는 것입니다. 그것이 제 생각에 장려되어야 할 것입니다.
CMCDragonkai
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.