내가 한 대답 내가 읽고 내가 기초 이해 생각 파이썬에서 절대 수입에 관한 질문 파이썬 2.5 변경 로그를 하고 동반 PEP를 . 그러나 Python 2.5를 설치하고을 올바르게 사용하는 예제를 만들려고 할 때 from __future__ import absolute_import
상황이 명확하지 않다는 것을 알고 있습니다.
위의 변경 로그에서 바로이 진술은 절대 수입 변경에 대한 나의 이해를 정확하게 요약했습니다.
다음과 같은 패키지 디렉토리가 있다고 가정 해 봅시다.
pkg/ pkg/__init__.py pkg/main.py pkg/string.py
이것은 패키지라는 이름을 정의합니다
pkg
pkg.main
and 및pkg.string
submodules를 포함 .main.py 모듈의 코드를 고려하십시오. 명령문을 실행하면 어떻게됩니까
import string
? Python 2.4 및 이전 버전에서는 먼저 패키지 디렉토리에서 상대 가져 오기를 수행하고 pkg / string.py를 찾은 다음 해당 파일의 내용을pkg.string
모듈 로 가져오고 해당 모듈은 모듈의 네임 스페이스"string"
에서 이름 에 바인딩됩니다pkg.main
.
그래서 나는이 정확한 디렉토리 구조를 만들었습니다 :
$ ls -R
.:
pkg/
./pkg:
__init__.py main.py string.py
__init__.py
그리고 string.py
비어 있습니다. main.py
다음 코드를 포함합니다 :
import string
print string.ascii_uppercase
예상대로 Python 2.5에서 이것을 실행하면 다음과 같이 실패합니다 AttributeError
.
$ python2.5 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
그러나 2.5 변경 로그에서 추가로 다음을 발견했습니다 (강조 추가).
Python 2.5에서는 지시문을
import
사용하여의 동작을 절대 가져 오기로 전환 할 수 있습니다from __future__ import absolute_import
. 이 절대 가져 오기 동작은 이후 버전 (아마도 Python 2.7)에서 기본값이됩니다. 절대 가져 오기가 기본값이면import string
표준 라이브러리 버전을 항상 찾습니다.
따라서 추가 미래 수입 지침과 pkg/main2.py
동일 main.py
하지만 을 만들었습니다 . 이제 다음과 같이 보입니다 :
from __future__ import absolute_import
import string
print string.ascii_uppercase
그러나 파이썬 2.5에서 이것을 실행하면 …로 실패합니다 AttributeError
.
$ python2.5 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
이것은 절대 가져 오기를 사용하여 항상 std-lib 버전을 찾는 명령문과 완전히 모순 import string
됩니다 . 또한 절대 가져 오기가 “새로운 기본값”동작으로 예정되어 있다는 경고에도 불구하고 지시문의 유무에 관계없이 Python 2.7을 사용하여 동일한 문제를 겪었습니다.__future__
$ python2.7 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
$ python2.7 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print string.ascii_uppercase
AttributeError: 'module' object has no attribute 'ascii_uppercase'
파이썬 3.5와 함께 또는없이 ( print
문이 두 파일에서 변경 되었다고 가정 ) :
$ python3.5 pkg/main.py
Traceback (most recent call last):
File "pkg/main.py", line 2, in <module>
print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'
$ python3.5 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 3, in <module>
print(string.ascii_uppercase)
AttributeError: module 'string' has no attribute 'ascii_uppercase'
나는 이것의 다른 변형을 테스트했습니다. 대신 string.py
라는 디렉토리 – 나는 빈 모듈을 만든 string
경우에만 빈 함유 __init__.py
– 대신에서 수입을 발행 main.py
, 나는이 cd
‘에 D를 pkg
하고 REPL에서 직접 수입을 실행합니다. 이러한 변형 (또는 이들의 조합) 중 어느 것도 위의 결과를 변경하지 않았습니다. __future__
지시문과 절대 수입에 대해 읽은 내용으로 이것을 조정할 수 없습니다 .
이것은 다음과 같이 쉽게 설명 할 수 있는 것 같습니다 (Python 2 문서에서 왔지만이 문장은 Python 3의 동일한 문서에서 변경되지 않았습니다).
sys.path
(…)
프로그램 시작시 초기화 된이 목록의 첫 번째 항목은
path[0]
Python 인터프리터를 호출하는 데 사용 된 스크립트가 포함 된 디렉토리입니다. 스크립트 디렉토리를 사용할 수없는 경우 (예 : 인터프리터가 대화식으로 호출되거나 표준 입력에서 스크립트를 읽는 경우)path[0]
빈 문자열 은 파이썬이 현재 디렉토리에서 모듈을 먼저 검색하도록 지시합니다.
그래서 내가 무엇을 놓치고 있습니까? 그 __future__
진술이 왜 말을하지 않는 것 같으며,이 두 문서 섹션 사이에, 그리고 설명 된 행동과 실제 행동 사이에이 모순의 해결책은 무엇입니까?
답변
변경 기록은 구식입니다. from __future__ import absolute_import
어떤 것이 표준 라이브러리의 일부인지에 대해 신경 쓰지 않으며 import string
절대 가져 오기가 항상 표준 라이브러리 모듈을 제공하지는 않습니다.
from __future__ import absolute_import
즉 import string
, Python은 항상 최상위가 string
아닌 최상위 모듈을 찾습니다 current_package.string
. 그러나 파이썬이 어떤 파일이 string
모듈 인지 결정하는 데 사용하는 논리에는 영향을 미치지 않습니다 . 당신이 할 때
python pkg/script.py
pkg/script.py
파이썬 패키지의 일부처럼 보이지 않습니다. 정상적인 절차에 따라, pkg
디렉토리 경로에 추가하고, 모든되는 .py
파일에서pkg
이 최상위 모듈처럼 보입니다. import string
발견 pkg/string.py
은 상대적으로 수입을하고 있기 때문에 아니지만, 때문에 pkg/string.py
나타납니다 최상위 모듈로 string
. 이것이 표준 라이브러리가 아니라는 사실string
모듈이 아니라는 나타나지 않습니다.
pkg
패키지의 일부로 파일을 실행하려면 다음을 수행하십시오.
python -m pkg.script
이 경우 pkg
디렉토리가 경로에 추가되지 않습니다. 그러나 현재 디렉토리가 경로에 추가됩니다.
또한 상용구의 pkg/script.py
일부로 파이썬을 처리하도록 상용구를 추가 할 수 있습니다pkg
파일로 실행할 때도 패키지의 .
if __name__ == '__main__' and __package__ is None:
__package__ = 'pkg'
그러나 이것은 영향을 미치지 않습니다 sys.path
. pkg
경로 에서 디렉토리 를 제거하려면 추가 처리가 필요 하며 pkg
상위 디렉토리가 경로에 없으면 경로에서도 해당 디렉토리를 고정해야합니다.
답변
절대 가져 오기와 상대 가져 오기의 차이점은 패키지에서 모듈을 가져오고 해당 모듈에서 해당 패키지에서 다른 서브 모듈을 가져 오는 경우에만 적용됩니다. 차이점을보십시오 :
$ mkdir pkg
$ touch pkg/__init__.py
$ touch pkg/string.py
$ echo 'import string;print(string.ascii_uppercase)' > pkg/main1.py
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "pkg/main1.py", line 1, in <module>
import string;print(string.ascii_uppercase)
AttributeError: 'module' object has no attribute 'ascii_uppercase'
>>>
$ echo 'from __future__ import absolute_import;import string;print(string.ascii_uppercase)' > pkg/main2.py
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>>
특히:
$ python2 pkg/main2.py
Traceback (most recent call last):
File "pkg/main2.py", line 1, in <module>
from __future__ import absolute_import;import string;print(string.ascii_uppercase)
AttributeError: 'module' object has no attribute 'ascii_uppercase'
$ python2
Python 2.7.9 (default, Dec 13 2014, 18:02:08) [GCC] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
>>>
$ python2 -m pkg.main2
ABCDEFGHIJKLMNOPQRSTUVWXYZ
참고 python2 pkg/main2.py
다른 문제가 다음 실행 가지고 python2
오기 다음과 pkg.main2
을 사용하는 것과 동일하다 (-m
스위치).
패키지의 서브 모듈을 실행하려면 항상 -m
인터프리터가 체인을 연결하지 못하게하는 스위치를 사용 하십시오sys.path
목록 하고 하위 모듈의 의미를 올바르게 처리하는 .
또한 패키지 하위 모듈에 대해 명시 적 상대 가져 오기를 사용하는 것이 좋습니다. 실패한 경우 더 많은 의미와 오류 메시지를 제공하기 때문입니다.