Modules & Packages

김현우·2020년 7월 23일
0
post-thumbnail

1. sys.modules 와 sys.path 의 차이점은 무엇일까?

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를 찾는 순서

  1. sys.modules
  2. built-in modules
  3. sys.path
  4. 못 찾으면 ModuleNotFoundError 에러를 리턴

2. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까?

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':  ...

해본 결과,

  • sys.modules 코드를 실행해보면 sys 모듈 또한 built-in 모듈중 하나임을 확인 가능
  • 파이썬에 이미 built-in 되어있는 내장 모듈이며,
  • 파이썬 설치시 기본적인 내장 모듈의 path 정보가 default값으로 지정

3. Absolute path and Relative path (절대경로와 상대경로)

파이썬의 built-in 모듈pip 을 통해 설치한 외부 모듈 및 package는 일반적으로 import 하는데 큰 문제가 되지 않지만,
직접 개발한 local package를 import 할때는 해당 package의 위치에 맞게 import 경로를 잘 선언해야 한다.

Local package를 import 하는 경로

  1. absolute path
from <모듈경로1>.<모듈경로2> import <변수/함수/클래스>
  1. 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를 사용 권장!

4. calculator 패키지 만들기


파일 생성!!

5. main module 에서는 패키지의 모듈을 어떻게 import 해야 할까?

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

작성 후 메인을 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가 나온다.

6. add_and_multiply.py에서 multiply함수를 절대경로와 상대경로도 각각 임포트 해보고 main 모듈과 차이점을 생각해보고 결과를 출력해보자!


상대경로 사용

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가 아니면 절대든 상대든 상관없다.

7. __init__.py 파일의 역할

  • __init__.py 파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.
  • 디렉터리에 __init__.py 파일이 없다면 패키지로 인식되지 않을 수도 있습니다.
    (📌 python3.3 버전부터는 __init__.py 파일이 없어도 패키지로 인식)

📌 참고

__all__란?

  • 특정 디렉터리의 모듈을 *를 이용하여 import할 때에는 다음과 같이 해당 디렉터리의 __init__.py 파일에 __all__이라는 변수를 설정하고 import할 수 있는 모듈을 정의해 주어야 함
  • __all__로 정의하지 않으면 인식되지 않습니다.
profile
코딩을 잘하는 개발자가 되자!

0개의 댓글