sys는 파이썬에 포함되어있는 모듈이다.
sys.modules와 sys.path를 출력과 수정 가능!!
import sys
print(sys.path)
print(sys.modules)
sys.modules
- 파이썬이 모듈이나 package를 찾기위해 가장 먼저 확인하는 곳
- 단순한 dictionary
- 이미 import된 모듈과 package들을 저장 (한번 사용한 것은 다시 찾지 않아도 됨)
- 새로 import 하는 모듈은 sys.modules 에서 찾을 수 없음
sys.path
- 파이썬이 모듈이나 패키지를 찾는 가장 마지막 장소
- import된 모듈의 경로를 string의 값으로 list(배열)에 저장되어 관리
- 새로운 패키지나 모듈을 사용하려면 이곳에 경로를 등록
sys.path
는 모듈과 패키지의 검색 경로와 순서를 변경가능. 내가 만든 모듈과 패키지의 검색 경로를 append() 함수로 list(배열)에 추가하여 사용 가능.
sys.modules
import한 모듈이 { 모듈이름 : 모듈경로 } 형태로 dictionary형.
참고 )
파이썬이 모듈/package를 찾는 순서
sys 모듈이 대해 알아보기 위해 sys.modlues를 직접 출력시켜 보았다.
>> import sys
>> print(sys.modlues)
# 결과값
{'sys': <module 'sys' (built-in)>, 'builtins': <module 'builtins' (built-in)>, '_frozen_importlib': <module 'importlib._bootstrap' (frozen)>, '_imp': <module '_imp' (built-in)>, '_warnings': <module '_warnings' (built-in)>, '_frozen_importlib_external': ...
해본 결과,
파이썬의 built-in 모듈
과 pip
을 통해 설치한 외부 모듈 및 package는 일반적으로 import 하는데 큰 문제가 되지 않지만,
직접 개발한 local package
를 import 할때는 해당 package의 위치에 맞게 import 경로를 잘 선언해야 한다.
Local package를 import 하는 경로
absolute path
from <모듈경로1>.<모듈경로2> import <변수/함수/클래스>
relative path
from .<모듈경로1>.<모듈경로2> import <변수/함수/클래스>
Absolute Path
는 절대적인 경로로, module이나 package를 import 할때 최상위 경로부터 선언! 일반적으로 local package를 import할때 사용. 경로를 길게 표시해야하는 단점.
Relative Path
는 상대적인 경로로, module이나 package를 import 할때, 현재 자신의 위치를 기준으로 상대적인 경로를 선언! 일반적으로 local package안에 다른 local package를 import할때 사용. 파일의 위치가 변경되었을 때, 찾을 수 없다는 것이 단점.
경로 표현 방법
- / : 루트위치
- .(dot)/ : 현재 디렉토리
- ../ : 현재위치에서 상위디렉토리로 이동
🧨주의🧨
Relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점은 있지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있음. 그러므로 웬만한 경우 absolute 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))
from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
def multiply(a,b):
return(a*b)
작성 후 메인을 run하면 아래와 같은 오류 발생!
__name__
에 대하여 먼저 알아보자면,
모듈의 이름이 저장되는 변수이며, 스크립트 파일을 직접 실행했을 때는 모듈의 이름이 아니라 'main'이 들어간다!
>> print(__name__)
#결과값
__main__
따라서, '__name__'
== '__main__'
이 된다.
상대경로를 통한 import는 현재 모듈의 이름에 기반함. main.py(메인 모듈)의 이름은 항상 __main__
이기 때문에 파이썬 앱에서 메인 모듈로 사용하기를 원하는 모듈들은 항상 절대경로를 사용함!!
main.py 모듈에서는 다른 모듈이나 패키지를 import 할 때 절대경로를 사용이 필수!!
따라서 상대경로가 아닌 절대경로로 설정하여 해결한다.
# 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가 나온다.
상대경로 사용
from .multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
# 결과값
>> 5
절대경로 사용
from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
# 결과값
>> 5
add_and_multiply.py는 __main__.py
가 아니기 때문에 절대 경로와 상대 경로 모두 결과가 잘 나온다.
__main__.py
가 아니면 절대든 상대든 상관없다.
__init__.py
파일의 역할__init__.py
파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.__init__.py
파일이 없다면 패키지로 인식되지 않을 수도 있습니다.__init__.py
파일이 없어도 패키지로 인식)📌 참고
__all__
란?
__init__.py
파일에 __all__
이라는 변수를 설정하고 import할 수 있는 모듈을 정의해 주어야 함__all__
로 정의하지 않으면 인식되지 않습니다.