Python module과 package

Junyoung Lee·2021년 6월 12일
0

Python

목록 보기
6/6


Python의 module과 package관련 몇 가지 적어보려고 한다!


Module? Package?

  • Module이란 각종 변수, 함수, 클래스를 담고 있는 파일
  • Package란 여러 모듈들을 묶어놓은 것

이미 만들어져있는 Module, Package를 불러오거나 만들어서 파일안에 따로 코드를 적을 필요 없이 변수, 함수, 클래스 등을 사용할 수 있다


Import search 순서

  1. sys.modules
  • Pythonmodule이나 package를 찾기 위해 가장 먼저 확인하는 곳
  • 단순한 dict이고 이미 import된 module과 package를 저장하고 있음
    -> 새로 Import하는 module은 sys.modules에서 찾을 수 없음
  1. built-in modules
  • Python에서 제공하는 공식 라이브러리
  • built-in module은 이미 Python에 포함되어 나와서 쉽게 찾아짐
  1. sys.path
  • 마지막으로 확인하는 곳
  • sys.path는 기본적으로 list이며 string요소들을 가지고 있음
  • list의 각 경로를 확인하면서 해당 경로에 package가 위치 해 있는지 확인함

sys.path에서도 찾지 못하면 ModuleNotFoundError를 리턴함


Absolute Path & Relative Path

직접 개발한 Local package를 import 할 때는 해당 package위치에 맞게 import 경로를 잘 선언해야 하는데 경로를 선언하는 방법은 Absolute PathRelative Path가 있다!

1) Absolute Path

  • 절대 경로
  • import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하게 동작한다
  • 경로의 시작점이 project의 가장 최상위 디렉토리에서 시작
  • 동일 project내에서는 어느 파일, 어느 위치에서 import하던지 경로가 항상 동일하게 되어 absolute path라고 함

2) Relative Path

  • Absolute Path와는 다르게 project의 최상단 디렉토리를 기준으로 경로를 잡는게 아닌 import하는 위치 기준
  • local package안에서 다른 local package를 import할 때 사용됨
  • from . import test1같이 .으로 import가 선언되는 파일의 현재 디렉토리로, ..를 사용하면 현재 디렉토리에서 상위 디렉토리부분도 사용 가능
  • Absolute Path보다 경로의 길이를 줄일 수 있음
  • 헷갈리기 쉽고 파일 위치 변경되었을 경우 경로 위치도 수정해줘야함
  • 웬만한 경우 Absolute Path 사용 권장됨

Assignment

1. sys.modules와 sys.path의 차이?

  1. Import Search순서가 첫 번째와 세 번째로 다름
  2. sys.modulesdictionary, sys.pathlist
  3. sys.modules는 이미 import된 module과 package를 저장하여 Python이 다시 찾지 않아도 되게하는 기능이고 sys.path는 import할 경로를 가지고 있음

2. sys도 import해야하는 module인데 python은 sys module의 위치를 어떻게 찾을 수 있을까?

sys module은 파이썬에서 제공하는 Built-in module이기 때문에 python이 바로 탐색이 가능하다


3. Absolute path와 relative path의 차이점?

  1. 절대경로와 상대경로
  2. 경로의 시작점이 Absolute path는 프로젝트의 최상위 디렉토리이고 relative path는 현재 디렉토리
  3. 위치가 바뀌었을 때 absolute path는 수정이 필요 없으나 relative path는 수정이 필요함

4. calculator package 만들어 보기

package를 한번 만들어보자!

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))

__init__.py👇🏻

# init파일은 아무 내용도 없지만 해당 디렉토리가 package임을 알려주는 역할!

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)

5. 위 main.py에서 상대경로로 add_and_multiply를 import했을 때 왜 에러가 나는 것일까?

relative path로 import를 하게 될 경우 기준이 되는 module의 위치를 정할 때 __name__속성에 의해 결정되는데 직접 실행시키는 module의 경우 __name__속성이 __main__이 되고 interpreter는 __main__이라는 module의 위치를 알 수 없기 때문에 에러가 발생한다

에러 해결을 위해서는 직접 실행시키는 module에서의 import는 absolute path로 진행하면 된다


6. add_and_multiply.py에서 multiply함수를 absolute path와 relative path로 import하고 main module과의 차이점 & 결과 출력

main.py에서 absolute path로 add_and_multiply module을 import했고 add_and_multiply__name__을 확인해보기 위해 Import했을때 __name__을 출력할 수 있도록 코드를 수정해 줬다

from .multiplication import multiply

print(__name__) # 추가해준 코드

def add_and_multiply(a,b):
    return multiply(a,b) + (a+b)

main.py에서 실행 결과👇🏻

calculator.add_and_multiply
5

add_and_multiply에서 출력한 __name__의 결과는 calculator.add_and_multiply로 확인할 수 있는데 이렇게 직접 실행하는 main이 아니면 relative path로 오류없이 정상적인 호출이 가능하다

물론 absolute path =>from calculator.multiplication import multiply로 호출해도 오류없이 정상적인 호출이 가능하다


7. __init__.py의 역할

  1. __init__.py__init__.py가 위치한 디렉토리를 Package module처럼 사용할 수 있도록 하는 기능

    Python 3.3 버전부터는 __init__.py가 없어도 package로 인식하지만 하위 버전 호환을 위해 파일을 생성하는 것이 좋음

  2. Python이 처음으로 package를 가져올 때 자동으로 디렉토리 안의 __init__.py에 있는 모든 코드를 실행하게 되므로 package에 있는 파일들에게 필요한 상태를 초기화하기 하는 용도로 설정하여 사용가능

  3. 파일 내부에 __all__이라는 리스트를 사용하여 import *을 할 때 불러올 module을 설정하여 원하는 module만 불러올 수 있게 할 수 있다

    from calculator.multiplication import *같이 마지막 항목이 module인 경우에는 __init__.py와 상관없이 전부 import됨
    (module 내에 __all__이라는 list에 함수명을 추가하면 해결가능)


작성된 부분 중 잘못 된 부분은 댓글로 feedback 부탁드립니다👊🏻👊🏻👊🏻👊🏻

profile
🎹재즈를 사랑하는 백엔드 개발자 이준영입니다🎷

0개의 댓글