Python Basics - How import statement finds modules and packages

Jayson Hwang·2022년 4월 28일
0

01. Import Search 순서

module일 경우에는 파이썬 파일, package의 경우 파이썬 파일들은 담고 있는 디렉토리들을 파이썬이 찾아야 import를 한다.
파이썬은 3가지 장소를 순서대로 보면서 찾는다.

sys.modules → built-in mudules → sys.path



02. sys.modules vs. sys.path

02-1. sys.modules

  • 파이썬이 module 이나 package를 찾기 위해 가장 먼저 확인하는 곳
  • 단순한 dictionary
  • 이미 imported module과 package를 저장하고 있음
    (한번 import된 module과 package들은 파이썬이 다시 찾지 않아도됨)
  • 따라서 새로 import하는 module은 sys.modules에서 찾을 수 없음

02-2. built-in modules

  • 파이썬에서 제공하는 파이썬 공식 라이브러리
  • built-in modules은 이미 파이썬에 포함되어 있어 쉽게 찾을 수 있음

02-3. sys.path

  • 파이썬 라이브러리들이 설치되어 있는 디렉터리를 보여줌
  • 파이썬이 module 이나 package를 찾을 때 가장 마지막으로 보는 장소
  • sys.path는 기본적으로 string요소들을 가지고 있는 list
  • sys.path에서도 못찾으면 ModuleNotFoundError를 리턴
import sys

print(sys.path)
['/Users/hwangjaeseung/Desktop/Back-End/Wecode Repl.it WorkSpace', '/Library/Frameworks/Python.framework/Versions/3.10/lib/python310.zip', '/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10', '/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages']

02-4. 결론(차이점)

  • sys.modules:: 파이썬이 제일 먼저 확인하는 장소이며 Dictionary
  • sys.path:: 파이썬이 제일 마지막에 확인하는 장소이고 List


03. 파이썬이 sys 모듈의 위치 찾는 방법

sys:: 파이썬에 포함된 모듈이기때문에 built-in modules에서 찾을 수 있음



04. Absolute path vs. Relative path

  • built-in 모듈과 pip를 통해 설치한 외부 모듈 및 package는 일반적으로 import 하는데 큰 문제 없음
  • 문제는 직접 개발한 local package
    local package를 import할때는 해당 Package의 위치에 맞게 import경로를 잘 선언해야함

04-1. Absolute Path

  • import를 하는 파일이나 경로에 상관없이 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡음
  • 일반적으로 local package를 import를 할때는 absolute path를 사용
    but, 경로가 길어질 수 있음

04-2. Relative Path

  • import하는 위치를 기준으로 경로를 정의
  • 일반적으로 local package 안에서 다른 local package를 import할 때 사용
  • dot(.)은 import가 선언되는 파일의 현재 위치
  • dot 2개(..)는 현재위치에서 상위 디렉토리로 가는 경로

04-3. Absolute path와 relative path의 차이점

  • absolute path::
    import를 하는 파일이나 경로에 상관없이 프로젝트의 최상단 디렉토리를 기준으로 경로를 정의

  • relative path::
    import하는 위치를 기준으로 경로를 정의



05. Calculator


main.py


# absoulte path
#from calculator.add_and_multiply import add_and_multiply 

# relative path
from .calculator.add_and_multiply import add_and_multiply

if __name__ == '__main__':
    print(add_and_multiply(1,2))

add_and_multiply.py

from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)

multiplication.py

def multiply(a,b):
    return(a*b)

위와 같이 실행 시, 아래와 같은 오류 발생.

  File "/Users/hwangjaeseung/Desktop/Back-End/Wecode Repl.it WorkSpace/main.py", line 5, in <module>
    from .calculator.add_and_multiply import add_and_multiply
ImportError: attempted relative import with no known parent package

부모 패키지가 정의되어있지 않은 상태에서 relative path로 import를 시도해서 발생한 에러



06. ImportError가 발생한 이유

파이썬 공식 문서에서는 해당 에러와 관련하여 다음과 같이 설명하고 있다.

따라서,
main.py의 relative path -> absoulte path로 변경하면


# absoulte path
from calculator.add_and_multiply import add_and_multiply 

# relative path
#from .calculator.add_and_multiply import add_and_multiply

if __name__ == '__main__':
    print(add_and_multiply(1,2))

문제없이 "5"가 출력된다.



07. Relative path and Absolute path in add_and_multiply.py

Absolute path

from calculator.multiplication import multiply
def add_and_multiply(a,b):
    return multiply (a,b) + (a+b)
    
# 출력결과: "5"

Relative path

from .multiplication import multiply
def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)
    
# 출력결과: "5"
  • add_and_multiply.py는 calculator 패키지에 있는 모듈이기 때문에
    absolute path 이던지 relative path 이던지 상관없이 실행된다.


08. __init__.py의 역할

  • 파일이 존재하는 디렉터리가 패키지임을 명시
    즉, 해당 디렉터리가 패키지의 일부임을 알려주는 역할

  • ex) add_and_multiply.py와 multiplication.py 패키지에 포함된 디렉터리에 init.py 파일이 없다면 패키지로 인식 X

profile
"Your goals, Minus your doubts, Equal your reality"

0개의 댓글