파이썬은 모듈/package를 다음 3가지 장소를 순서대로 보면서 찾습니다.
파이썬이 모듈이나 package를 찾기위해 가장 먼저 확인 하는 곳입니다.
sys.modules는 단순한 dictionary입니다. 그리고 이미 import된 모듈과 package들을 저장하고 있습니다.
즉, 한번 import된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되도록 하는 기능을 가지고 있습니다.
그러므로 새로 import하는 모듈은 sys.moduled에서 찾을 수 없습니다.
파이썬에서 제공하는 파이썬 공식 라이브러리들입니다.
Built-in 모듈은 이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있습니다.
마지막으로 보는 장소가 바로 sys.path입니다.
sys.path는 기본적으로 list이며 string요소들을 가지고 있는 list입니다.
각 string 요소들은 다음처럼 경로를 나타냅니다.
그러므로 파이썬은 list의 각 경로를 하나 하나 확인하면서 해당 경로에 import 하고자 하는 package가 위치해 있는지 확인합니다.
참고로 sys는 파이썬에 포함되어 있는 모듈입니다. 그러므로 다음처럼 sys모듈을 import해서 sys.modules와 sys.path를 출력할수도 있고 수정할 수도있습니다.
마지막 sys.path에서도 못찾으면 ModuleNotFoundError에러를 리턴합니다.
sys.modules
1. sys.modules 이전에 import 한 모듈이나 패키지가 저장되기 때문에 새로운 모듈과 패키지는 저장되지 않습니다.
2. 가장 파이썬이 모듈과 패키지를 찾을 때 가장 우선적으로 sys.modules에서 살펴봅니다.
3. dictionary구조 입니다.
sys.path
1. 마지막으로 보는 장소입니다.
2. list구조이며 element는 string형태입니다.
Absolute path는 이름 그대로 절대 경로입니다. 왜 절대 경로인가 하면, import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문입니다.
다음과 같은 프로젝트를 예로 들어 보겠습니다.
l
my_app이라는 프로젝트이며 package1과 package2라는 2개의 package를 가지고 있습니다.
그리고 package2는 subpackage2라는 중첩 package를 가지고 있습니다.
l
Absolute path를 사용해 package1과 package2를 import 하면 다음과 같습니다.
예를 들어, subpackage1의 module5모듈의 funcion2 함수를 import 하기 위해서는 다음 경로를 거치게 됩니다.
파이썬에서는 dot(.)을 사용해서 경로를 표현 합니다.
이미 my_app프로젝트 안에 있으므로 my_app은 생략됩니다. 그러므로 다음처럼 경로를 표현하게 되는 것입니다.
이것을 from import키워드를 사용해 import하게되면 다음 처럼 되는 것입니다.
뒤에는 function2입니다.
my_app 프로젝트 내에서는 어느 파일, 어느 위치에서 import하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path라고 하는 것입니다.
absolute path는 한 가지 단점이 있습니다.
바로 경로가 길어질 수 있다는점입니다.
그래서 이러한 단점을 보완하기 위해서 relative path를 사용합니다.
Relative path는 absolute path와 다르게 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는게 아니라 import하는 위치를 기준으로 경로를 정의합니다. 그래서 일반적으로 relative path는 local package 안에서 다른 local package를 import할 때 사용됩니다.
예를 들어, package2의 module3에서 package2의 class1과 package2의 하위 package인 subpackage1의 module5의 function2 함수를 import하려고 하면 다음 처럼 할 수 있습니다.
여기서 dot(.)은 import가 선언되는 파일의 현재 위치를 이야기 합니다. 현재위치는 package2/module3.py 이므로 현재 위치에서부터 원하는 모듈의 경로만 선언해주면 되는 것입니다.
또한 dot 2개를 사용할 수도 있습니다. dot 2개(..)는 현재위치에서 상위 디렉토리로 가는 경로입니다.
Relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점은 있지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있습니다. 그러므로 웬만한 경우 absolute path를 사용하는것을 권장합니다.
Absolute path
1.가장 상위프로젝트 기준으로 어느 파일, 어느 위치에서 import하던지 경로가 항상 같습니다.
2. 경로의 길이가 길어진다는 단점이 있습니다.
Relative path
1.가장 상위 프로젝트 기준이 아닌 자신이 import하는 위치를 기준으로 경로를 정의 합니다.
2. 경로의 길이가 줄여준다는 장점은 있지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있습니다..
sys 도 import 해야하는 모듈입니다. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까요?
sys를 import하여 출력하면 다음과 같은 출력화면이 나타납니다.
즉, sys는 built-in내의 있습니다. built-in 파이썬에서 공식 라이브러리 입니다. sys는 파이썬에서 기본적으로 제공이 된다는 것입니다.
일단 패키지 및 파일들을 만듭니다.
만들고 나면 이제 코딩을 합니다.
main.py
"__name__" == "__main__"은 interpreter에서 직접 실행할때만 if문내의 코드를 실행하라는 뜻입니다.
from calculator.add_and_multiply import add_and_multiply은 만든 폴더인 calculator폴더에서 add_and_multiply파일에서 add_and_multiply함수를 가져온다는 뜻입니다.
근데 from calculator.add_and_multiply는 무조건 절대경로로 지정해줘야 합니다. 상대경로로 지정하면 다음과 같은 에러가 발생합니다.
print(add_and_multiply(1,2))은 가져온 add_and_multiply(1,2)를 실행하여 return 하여 print 하라는 것입니다.
__init__.py
__init__.py 파일을 포함한 폴더가 pakage라는 것을 알려주는 것입니다.
add_and_multiply.py
from .multiplication import multiply는 같은 폴더내의 .mutiplication내의 multiply함수를 가져오는 것입니다.
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)는 add_and_multiply(a,b)라는 함수를 정의하여multiply(a,b) + (a+b) return 합니다.
multiply(a,b)는 위에서 import한 함수입니다.
multiplication.py
a,b 매개변수를 받아 곱해서 return 하는 것입니다.
add_and_multiply.py에서 multiply함수를 절대경로와 상대경로 import후 실행
절대 경로
절대경로는 가장 상위 package부터 순서대로 가져와야 합니다.
상대 경로
상대경로는 지금 현재 파일을 기준에서 가져온면 된다. multiplication이 현재파일과 같은 폴더내의 있으므로 .(dot)를 통해서 가져오면 됩니다.
__init__.py은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 합니다.
또 디렉터리에 __init__.py 파일이 없다면 패키지로 인식되지 않을 수 있습니다.