sys.modules 와 sys.path 모두 파이썬이 모듈이나 package를 import하기 위해 먼저 확인한다는 점에서 공통점이 있지만 sys.modules는 dictionary, sys.path는 string 요소를 가진 list라는 점에서 차이가 있습니다.
sys.modules는
1. 파이썬이 모듈이나 package를 찾기 위해 가장 먼저 확인하고
2. 이미 import된 모듈과 package들을 저장하고 있은 dictionary이며
3. 한번 import된 모듈과 package들을 파이썬이 또 찾이 않아도 되도록 하는 기능을 가지고 있습니다. 그러므로 새로 import 되는 모듈은 찾을 수 없습니다.
sys.path는
['',
'/Users/song-eun-u/anaconda3/bin',
'/Users/song-eun-u/anaconda3/lib/python36.zip',
'/Users/song-eun-u/anaconda3/lib/python3.6',
'/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions',
'/Users/song-eun-u/.ipython']
위와 같이 경로를 나타내는 string으로 이루어진 list입니다.
파이썬이 모듈을 찾을때 가장 마지막으로 보는 장소이며
검색 시에는 list의 각 경로를 하나하나 확인하면서 해당 경로에 import하고자 하는
package가 위치하는지 확인합니다.
sys는 파이썬에 포함되어 있는 모듈이기 때문에
sys모듈을 import해서 sys.modules와 sys.path를 출력할수도 있고
수정할 수도 있습니다.
Absolute path는 절대경로 입니다.
from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2
위와 같이 경로의 시작점이 프로젝트의 가장 최상위에서부터 시작합니다.
import하는 파일이나 경로에 관계없이 항상 경로가 동일합니다.
Relative path는 상대경로 입니다. 절대경로와는 다르게
import하는 위치를 기준으로 아래와 같이 import 합니다.
#package2/module3.py
from . import class1
from .subpackage1.module5 import function2
import 왼쪽의 (.)은 import가 선언되는 파일의 현재 위치를 말합니다.
또한 (..)를 사용할 수도 있습니다. 현재 위치에서 상위 디렉토리로 가는 경로입니다.
상대경로는 선언해야 하는 경로의 길이를 줄여주는 장점이 있지만 파일 위치가 변경될 경우
같이 변경해 주어야 하는 단점이 있습니다.
에러내용
Traceback (most recent call last):
File "C:/develop/server_project/wecode/main.py", line 5, in <module>
from .calculator.add_and_multiply import add_and_multiply
ImportError: attempted relative import with no known parent package
main.py의 name을 print할 경우 main이 표시됩니다.
name이 main으로 표시되는 경우는 모듈이 다른 코드로부터 import되어 실행되는
경우가 아니라 바로 실행되어 지는 경우에 main으로 표시됩니다.
https://docs.python.org/3/tutorial/modules.html#intra-package-references
위의 문서의 내용에 따르면
Note that relative imports are based on the name of the current module. Since the name of the main module is always "main", modules intended for use as the main module of a Python application must always use absolute imports.
상대경로는 현재 모듈의 이름에 기반하여 가져와야 한다 명시되어있습니다.
main은 메인 모듈의 이름을 나타내며 메인 모듈에서는 항상 절대경로로 import 하기를
명시하고 있습니다.
그러므로 아래와 같이 절대경로를 사용하여 에러 해결이 가능합니다.
위와 같이 상대경로로 import하여 실행했을 경우 에러가 발생합니다.
Assignment5에서 언급하였던것처럼 다른 코드로부터 import되어 실행되는 것이 아니라 바로 실행되기 때문에 메인 모듈이 되며 위에 언급하였던것처럼 절대경로를 사용하여 import해야
합니다.
절대경로를 사용하여 import했을 경우 위와 같이 에러가 해결됩니다.
init.py의 내용은 비어있지만
폴더 안에 init.py파일이 있으면 해당 디렉토리가 패키지임을 알려주는 역할을 합니다.