Assignment
이번 과제는 코딩 과제가 아니라 서술형 과제입니다. 다음 문제들을 읽으시고 답을 블로깅 한후 슬랙 채널에 공유해주세요.
- sys.modules 와 sys.path의 차이점을 서술해 주세요.
- sys 도 import 해야하는 모듈입니다. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까요?
- Absolute path와 relative path의 차이점을 서술해 주세요.
1. sys.modules 와 sys.path의 차이점을 서술해 주세요.
파이썬은 module/package를 다음 3가지 장소를 순서대로 보면서 찾는다.
1.sys.modules
2.built-in modules
3.sys.path
sys.modules는 파이썬이 가장 먼저 확인 하는 곳이다.
sys 모듈은 파이썬 인터프리터가 제공하는 변수와 함수를 직접 제어할 수 있게 해주는 모듈이다.
sys.modulessms 단순한 dictionary이며 이미 import된 모듈과 패키지들을 저장하고 있다.
즉,한번 import된 모듈과 패키지들은 파이썬이 다시 찾지 않아도 되도록 하는 기능을 가지고 있다.
그러므로 새로 import하는 모듈은 sys.modules에서 찾을수가 없게 되는 것이다.
sys.path는 파이썬이 module/package를 찾을때 마지막으로 보는 장소이다.
기본적으로 list이며 string요소들을 가지고 있는 list이다.
각 string요소들은 경로를 나타낸다. 참고로 sys는 파이썬에 포함되어 있는 모듈이다.
그러므로 sys모듈을 import해서 sys.modules와 sys.path를 출력 할수도 있고 수정 할수도 있다.
sys.path에도 import하고자하는 모듈과 패키지를 파이썬이 찾지 못한다면 ModuleNotFoundError에러를 리턴하게 된다.
2.파이썬은 sys 모듈의 위치를 어떻게 찾는가?
'sys' : <module'sys'(bulit-in)>
sys모듈은 이미 bulit-in 되어 있기 때문에 built-in module들이 있는 부분에서 찾게된다.
- Absolute path와 relative path의 차이점
결론:import를 할때 경로의 시작점에 차이가 있다.
파이썬의 built-in 모듈과 pip 을 통해 설치한 외부 모듈 및 패키지는 일반적으로 import하는데 큰 문제가 되지 않는다. 하지만 직접 개발한 local package는 import할때 해당 패키지의 위치에 맞게 import 결로를 잘 선언해야 한다.
local package를 import하는 경로에는 absolute path 와 relative path 가 있다.
Absolute Path는 이름 그대로 절대경로이다.
import를 하느 파일이나 경로에 상관없이 항상 경로가 동일하다.
다음과 같은 프로젝트를 예를 들어 보겠습니다:
└── my_app
├── main.py
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
my_app 이라는 프로젝트 이며 package1과 package2라는 2개의 패키지를 가지고 있다. 그리고 패키지2는 subpackage2 라는 중첩 패키지를 가지고 있다.
Absolute path을 사용해 패키지1과 패키지2를 import하면 다음과 같다.
from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2
경로들의 시작점이 전부 "my_app"프로젝트의 가장 최상의 디렉토리에서 시작하고있다.
my_app 프로젝트 내에서는 어느 파일, 어느 위치에서 import하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path라고 하는것이다.
참고로 current directory 라고 하는 현재의 프로젝트 디렉토리는 default로 sys.path에 포함되게 된다.
그러므로 absoulute path는 current directory 로 부터 경로를 시작하게 되는 것이다.
일반적으로 local package를 import 할때는 absolute path를 사용하면 된다.
다만 경로가 길어질 수 있다는 단점이 있다.
이러한 단점을 보완하기 위해서 relative path를 사용 할 수 있다.
Relative path 는 import하는 위치를 기준으로 경로를 정의한다는 점에서 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는 absolute path와 차이가 있다.
└── my_app
├── main.py
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
위의 프로젝트에서 패키지2의 모듈3에서 패키지2의 클래스1과 패키지2의 하위 패키지인 서브패키지1의 모듈5의 function2 함수를 import 하려고 하면 다음 처럼 할 수 있다.
# package2/module3.py
from . import class1
from .subpackage1.module5 import function2
여기서 dot(.)는 import가 선언되는 파일의 현재 위치를 이야기한다.
현재 위치는 package2/module3.py이므로 현재 위치에서부터 원하는 모듈의 경로만 선언해주면 되는 것이다.
또한 dot 2개 ( .. ) 는 현재 위치에서 상위 디렉토리로 가는 경로이다.
# subpackage1/module5.py
from ..module4 import class4
Relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점은 있지만,
헷갈리기 쉽고 파일의 위치가 변경되면 경로 위치도 변경 되어야 한다는 단점이 있다.
그러므로 웬만한 경우에는 absolute path를 사용하는게 권장된다.
추가
다음과 같은 패키지를 생성했고,
실행된다. 패키지의 구조를 알려주었기 때문에 파이썬은 상대경로를 찾을수가 있다.
패키지2 내의 init.py을 불러들이면
해당 에러가 뜬다.
패키지 내부에서는 상대경로가 가능하지만, 패키지를 실행하는 모듈안의 함수를 호출하는 파일에서는 상대경로가 안된다.
(파이썬 자체에서 막아놨다고 한다..)