파이썬이 모듈과 패키지를 검색하는 방법
import search 순서
- abc package를 사용하려면 다음처럼 import 해야한다.
import abc
- 여기서 abc는 단순한 파이썬 파일(모듈일 경우 )이거나 파이썬 파일들을 담고 있는 디렉토리(package의 경우)이다.
- 그러므로 해당 파일이나 디렉토리가 어디있는지 파이썬이 찾을 수 있어야 import 가 가능하다.
파이썬은 모듈과 패키지를 다음 3가지 장소를 순서대로 보면서 찾는다
1. sys.modules
2. built-in modules
3. sys.path
sys.modules
- 파이썬이 모듈이나 패키지를 찾기 위해 가장 먼저 확인하는 곳이다.
- sys.modules는 단순한 dictionary이다. 그리고 이미 import된 모듈과 package들을 저장하고 있다.
- 즉 한번 import 된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되도록 하는 기능을 가지고 있다. 그러므로 새로 import하는 모듈을 sys.modules에서 찾을 수 없다.
built-in modules
- 파이썬에서 제공하는 파이썬 공식 라이브러리들이다.
- built-in 모듈들은 이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있다.
sys.path
-
마지막으로 보는 장소가 sys.path이다.
-
sys.path는 기본적으로 list 이며 string요소들을 가지고 있는 list 이다
-
각 string요소들은 다음처름 경로를 나타낸다.
-
파이썬은 list의 각 경로를 하나하나 확인하면서 해당 경로에 import 하고자 하는 packpage가 위치해 있는지 확인한다.
sys는 파이썬에 포함되어있는 built-in module이다.
'sys': <module 'sys' (built-in)>
다음처럼 sys모듈을 import해서 sys.modules 와 sys.path를 출력할 수도 있고 수정할 수도 있다.
import sys
print(sys.path)
print(sys.modules)
- 파이썬은 imoprt하고자 하는 모듈과 package를 찾을 때에 먼저 sys.modules를 보고, 없으면 파이썬 built-in 모듈들을 확인하고, 마지막으로 sys.path에 지정되어 있는 경고들을 확인해서 찾는다.
- sys.path에서도 못찾으면 ModuleNotFoundError 에러를 리턴한다.
absolute path & relative path
- 직접 개발한 local package를 import할때는 해당 패키지의 위치에 맞게 import 경로를 잘 선언해야 한다.
- local package를 import하는 경로에는 absolutepath 와 relative path가 있다.
absolute path
- absolute path 이름 그대로 절대경로이다. Import하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문이다.
- absolute path 를 사용해 package1과 package2를 import하면 다음과 같다.
from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2
- 파이썬에서는 dot(.)을 사용해서 경로를 표현한다.
- 경로들의 시작점은 전부 my_app 프로젝트의 가장 최상위 디렉토리에서 시작한다.
my_app 프로젝트의 subpackage1의 module5 모듈의 function2함수를 import하기 위해서는 my_app.package2.subpackage1.module5.py 의 경로를 거치게 된다.
- my_app 프로젝트 안에 있으므로 my_app은 생략될 수 있다.
- my_app프로젝트 내에서는 어느 파일, 어느 위치에서 import하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path라고 한다.
- 일반적으로 local package를 import 할때는 absolute path를 사용하면 된다.
다만 단점은 경로가 길어질 수 있다. 그래서 이러한 단점을 보완하기 위해서 relative path를 사용할 수 있다.
- current directory라고 하는 현재의 프로젝트 디렉토리는 default로 sys.path에 포함되게 된다.
그러므로 absolute path는 current directory로 부터 경로가 시작하게 된다
relative path
- relative path는 absolute path와 다르게 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡지 않고 import하는 위치를 기준으로 경로를 정의한다.
- 그래서 일반적으로 relative path는 local package 안에서 다른 local package를 imoport할 떄 사용된다.
- dot(.)은 import가 선언되는 파일의 현재 위치이며 현재 위치에서부터 원하는 모듈의 경로만 선언해주면 된다.
- dot 2개는 현재 위치에서 상위 디렉토리로 가는 경로이다. relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점이 있지만, 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있다.
modules & packages 실습
- mypg 폴더 안에 main.py 와 pkg1, pkg2 폴더를 생성한다.
- pkg1 폴더 안에
__init__
.py 과 mod1,mod2를 생성해 넣고, pkg2 폴더 안에 mod3을 생성해 넣어준다.
__init__
#__init__.py
from .mod1 import func2
from .mod2 import func3
__all__ = ['func2']
__init__
.py 파일을 사용해서 import 할 때 경로의 총 길이를 줄여줄 수 있다.
__all__
변수를 따로 정의해줌으로 import 될 수 있는 요소들을 제한할 수 있다.
#pkg1/mod1.py
def func2():
return "hello!"
#pkg1/mod2.py
def func3():
return "package"
#main.py
from pkg1 import *
print(func2())
print(func3())
__all__
변수는 import 되길 원하는 요소들을 string으로 list에 선언해주면 되는데 mod1의 func2만 있으므로 hello! 만 출력되고 func3의 package는 출력되지 않는다.
- absolute path & relative path
#pkg2/mod3
def func4():
return "absolute"
#main.py
from pkg2.mod3 import func4
print(func4())
#pkg2/mod3
def func4():
return "relative1"
#pkg2/mod4
from .mod3 import func4 #상대경로를 통해 mod3의 func4를 import 해온다.
def func5():
return "relative2"
import pkg2
print(pkg2.func4())
print(pkg2.func5())