Python Finds Modules & Packages

lentos·2020년 5월 29일
0

sys.modules 와 sys.path의 차이점

sys.modules

파이썬은 모듈이나 package가 호출 됐을 때 sys.modules -> built-in modules -> sys.path 순서로 검색을 시작한다.

import sys

print(sys.modules)

결과

{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module 'importlib._bootstrap' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' 

......

<module 'dis' from '/usr/lib/python3.8/dis.py'>, 'inspect': <module 'inspect' from '/usr/lib/python3.8/inspect.py'>, 'bdb': <module 'bdb' from '/usr/lib/python3.8/bdb.py'>, 'remotedebugger': <module 'remotedebugger' from '/run_dir/remotedebugger.py'>, 'subprocessdebugger': <module 'subprocessdebugger' from '/run_dir/subprocessdebugger.py'>}

sys.modules는 결과창에서 확인할 수 있듯이 단순한 dictionary이다. 한번이라도 import 된 적이 있는 모듈과 package들은 파이썬이 또 찾지 않아도 되도록 sys.modules 내에 저장된다. 따라서 import 한 적이 없는 새로운 모듈은 sys.modules에서 찾을 수 없다.

sys.path

import sys

print(sys.path)

결과

['/run_dir', '/opt/virtualenvs/python3/lib/python3.8/site-packages', '/usr/lib/python38.zip', '/usr/lib/python3.8', '/usr/lib/python3.8/lib-dynload']

파이썬이 sys.modules에서 이미 import 한 적이 있는 모듈들, built-in modules에서 기본적으로 제공되는 모듈들 모두 검색 후 마지막으로 찾아보는 장소이다. sys.path는 기본적으로 list이며 요소들은 모두 string 이다. 각 string 요소들은 각각 경로들을 나타낸다. 파이썬은 sys.path가 가지고 있는 경로들을 하나하나 검색한다. sys.path에서도 검색에 실패하면 ModuleNotFoundError 에러를 리턴한다.

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

sys 모듈은 파이썬 인터프리터와 관련된 정보와 기능을 제공하는 모듈이다. sys는 C언어로 프로그래밍 되어 파이썬 내에 내장되어 있기 때문에 따로 py 파일로 작성되어 있지 않다. 경로를 찾을 필요 없이 import sys를 해주면 파이썬에 내장된 sys 모듈을 바로 호출해온다.

Absolute path와 relative path의 차이점

Absolute path

import를 요청하는 파일의 경로에 상관없이 언제나 동일한 경로를 나타낸다.

최상위 위치는 my_app이라는 프로젝트 디렉토리이다. my_app은 current directory로 sys.path에 default 값으로 포함되어 있다. 따라서 my_app은 생략되며

위 경로들 처럼 최상위 위치부터 단계별로 내려가며 경로를 찾아간다.

relative path

검색이 시작되는 곳이 최상위 위치가 아닌 import를 요청한 위치가 시작점이 된다.

같은 시작점의 하위 package들을 호출할 경우 위의 그림처럼 경로값의 길이가 짧아지는 장점이 있다.

dot(.)을 두개를 사용할 경우 상위 디렉토리로 가게 된다.

relative path는 Absolute path에 비해 경로값의 길이를 줄여주는 장점은 있지만 파일의 위치가 변경될 경우 경로 역시 모두 변경되는 단점이 있기 때문에 사용이 권장되지는 않는다.

main.py 에서 relative path를 사용할 경우


Since the name of the main module is always "main", modules intended for use as the main module of a Python application must always use absolute imports.

파이썬 공식문서에 따르면 relative path는 현재 모듈의 이름을 기반으로 경로를 찾는다. 하지만 main 모듈의 이름은 언제나 "main"이므로 absolute path를 사용해야 한다.

경로 자체는 같지만 relative path 대신 absolute path로 수정했더니 정상적으로 코드가 작동한다.

relative path 와 absolute path의 함수 호출

relative path로 import할 경우 add_and_mutiply의 위치가 시작점이 된다. 같은 디렉토리의 multiplication 모듈을 찾은 후 모듈 내의 multiply 함수를 불러왔다.

absolute path로 import를 하게 되면 최상위 위치가 시작점이 된다. calculator 디렉토리에서 단계별로 내려오며 경로를 찾아간다.

다만 calculator는 최상위 디렉토리이기 때문에 생략을 하여도 정상적으로 코드가 동작한다.

init.py

init.py 파일은 이 파일이 존재하는 디렉토리는 패키지의 일부임을 알려주는 역할을 한다. 즉 이 파일이 없는 디렉토리는 패키지로 인식하지 않는다.

init.py에서 import 하고자 하는 함수를 한번만 호출해주면 다음부터는 바로 함수를 호출 할 수 있다.

또한 all변수에 import하고 싶은 요소들만 list 선언 해주면 import될 요소들을 제한해 줄 수 있다.

0개의 댓글