Python - Module & Package, Path

문성호·2020년 8월 22일
  • 파이썬에서 Module이란 함수, 변수, 클래스 등 코드들의 집합이다.
    사용자가 직접 제작할 수도 있지만, 파이썬 자체적으로 여러가지 필요한 Module들을 기본적으로 가지고 있다.

  • 사용하고 싶은 Module을 내 파일이나 프로젝트에 반영하려면 import를 해야 한다. 물론 시스템에 내장되어 있는 표준 모듈(sys, dateTime...)들은 import 시키지 않아도 이미 자동 import 되어 있다.
    그 외에 사용자가 필요로 하는 Module들이나 직접 사용자가 정의한 Module들은 따로 import 시켜야 한다.

Sys.modules, Sys.path, built-in

  • 파이썬은 코드 실행 시 필요한 Module들을 import하기 위해 모듈/패키지들을 찾는데, sys.modules -> built-in -> sys.path 순으로 모듈들을 찾는다.

    1. Sys.modules

    • 이미 import되어 있거나 한 번 import 되어 있던 module들을
      저장하고 있다. 한 번 사용했었기 때문에 또 다시 찾을 필요 없는 기능을 가지고 있는 것. (우선순위가 높을 가능성이 크다)

    • Dictionary 구조로 되어 있다.
    • 따라서 새로운 module들은 당연히 여기서 찾을 수 없을 것이다.

    2. Built-in module

    • 파이썬이 제공하는 모든 공식 라이브러리.

    3. Sys.path

    • sys.path는 기본적으로 list이며 string 요소들을 가지고 있는 list 입니다.
    • 파이썬의 경로 하나하나를 다 확인하면서 import 하고자 하는 모듈이나 패키지가 있는지 확인한다.
    • 외부 모듈이나 사용자 정의 모듈들도 이 과정에서 찾을 수 있다.

파이썬이 Sys 모듈의 위치를 찾는 방식

  • print(Sys.modules['sys']) 을 실행해보면 다음과 같이 나온다.
'sys': <module 'sys' (built-in)>
  • sys 모듈은 파이썬에 내장되어 있는 built-in 모듈이기 때문에, 2번째 단계에서 당연히 찾을 수 있다.

Absolute path vs Relative Path

  • 우리나라에는 두 개의 '광주시'가 존재한다.(경기도와 전라도)
    그러나 엄연히 도가 다르기 때문에 동이나 읍은 당연히 다를 것이다.
    경기도 광주시에 사는 사람을 붙잡고 전라도 광주 출신 사람이 동네 이야기를 하면 말이 안 통할 것이다. Absolute Path(절대 경로)와 Relative Path(상대 경로)도 이와 같이 이해할 수 있다.

└── my_app
    ├── main.py
    ├── package1
    │   ├── module1.py
    │   └── module2.py
    └── package2
        ├── __init__.py
        ├── module3.py
        ├── module4.py
        └── subpackage1
            └── module5.py

Absolute Path

  • Absolute paths는 모듈 및 패키지의 시작부터 끝까지 모두 서술한 경로다. '대한민국 경기도 광주시 XX동...'와 같다고 보면 된다.

  • 위와 같이 my_app이라는 프로젝트가 있으면 module4.py를 찾을 때
    from package2.module4 import function4
    와 같이 패키지-> 모듈 -> 함수까지 모든 주소를 다 망라하는 것이다.

Relative Path

  • Relative Path는 현재 작업 디렉토리에 있다는 전제하의 경로를 서술하는 것이다. 전라도에 있다는 전제하에 '광주시 XX동...'와 같다고 보면 된다.

  • 위와 같이 my_app이라는 프로젝트가 있으면 현재 Package2에서 작업하고 있다면,
    from .module4 import function4와 같이 설정하면 된다.
    .module4처럼 현재 디렉토리를 표현하려면 .을 붙이면 된다.

패키지(Calculator) 만들어보기

main module에서 모듈을 임포트할 때는 반드시 절대경로로 해야 한다.

  • 상대경로가 쓰일 수 없는 곳이 딱 한 곳 있는데, 프로젝트의 main module에서다.
    위의 Calculator 모듈의 main.py의 일부다.
# absolute 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))
  • absolute path로 import하면 정상 실행 되고, relative path로 하면 그렇지 않다.
  • https://docs.python.org/3/tutorial/modules.html#intra-package-references
    위 파이썬 문서를 보면 그 이유를 찾을 수 있는데,
    상대경로는 현재 모듈의 이름을 기반으로 하는데, 우리가 사용하기 위한 메인모듈은 항상 main이라는 이름의 모듈이기 때문에, 절대경로로 설정해서 해야한다고 한다.

init.py 파일의 역할

  • init.py는 제목 그대로 package를 initialize하는 역할을 한다.
    (1) 이 패키지가 이 프로젝트의 일부임을 확인시켜주고
    (2) import 할 경로의 길이를 줄여주고
    (3) 필요한 함수.클래스만 불러올 수 있다.

  • 위의 calculator 프로젝트의 main.py에서 calculator 패키지의 함수들을 불러오려면
from calculator.add_and_multiply import add_and_multiply

if __name__ == '__main__':
    print(add_and_multiply(1,2))
  • import 경로를 매우 길게 써야 했다.
    함수가 많아지고 모듈이 많아지면 더더욱 번거로워 것이다.
    따라서 main.py에서는 간결하게 from calculator import * 라고만 쓰고, 나머지는 해당 패키지(Calculator)에서 사용할 주요 함수들을 미리 import해놓는 것이다.

  • init.py에 상대경로로 이렇게 정의해놓으면 된다.
from .add_and_multiply import add_and_multiply

__all__ = ['add_and_multiply']
  • all은 필요한 함수의 목록이다. 실제로 calculator 패키지에는 multiply함수가 존재하지만, 필요하지 않기 때문에 불러오지 않을 수 있다.
profile
오늘을 모아 내일을

0개의 댓글