module과 package

Jinhyeon Son·2020년 3월 30일
0

개념

목록 보기
8/26

module

함수나 변수 또는 클래스를 모아놓은 파일

모듈안에서 동작하는 함수는 기본적으로 모듈의 scope을 참조한다
그렇기 때문에 모듈을 import해서 사용하더라도 전역 변수 끼리의 충돌을 걱정하지 않아도 된다
물론 module.globalvar로 접근하여 전역 변수를 참조 및 수정 할 수 있다

__name__ 객체

파이썬 파일이 실행 되면 인터프리터는 global 네임스페이스의 __name__ 객체를 "__main__"으로 설정한다
반면에 직접 실행되지 않고 import되었을 경우 해당 모듈의 __name__ 객체는 "모듈 이름"으로 설정 된다

  import sys

  print(__name__)
  print(sys.__name__)
  
  # 실행 결과 
  __main__
  sys

이를 이용해서

	if __name__ == __main__:
	위의 조건문 밑에 작성한 코드는 모듈이 import되었을 때는 실행되지 않다가
    	모듈이 main으로 실행되었을 때만 동작한다
        

C, JAVA등의 main함수와 같은 효과를 얻을 수 있다

모듈 탐색 순서

1. sys.modules

한번이라도 import된 모듈이나 package들은 sys.modules에 (모듈이름:모듈객체)형태의 
dictionary로 저장되어 모듈들의 캐시 역할을 한다
sys <module 'sys' (built-in)>
builtins <module 'builtins' (built-in)>
_frozen_importlib <module '_frozen_importlib' (frozen)>
_imp <module '_imp' (built-in)>
_thread <module '_thread' (built-in)>
_warnings <module '_warnings' (built-in)>
_weakref <module '_weakref' (built-in)>
zipimport <module 'zipimport' (built-in)>
_frozen_importlib_external <module '_frozen_importlib_external' (frozen)>
_io <module 'io' (built-in)>
marshal <module 'marshal' (built-in)>
posix <module 'posix' (built-in)>
encodings <module 'encodings' from '/usr/lib/python3.7/encodings/__init__.py'>
codecs <module 'codecs' from '/usr/lib/python3.7/codecs.py'>
_codecs <module '_codecs' (built-in)>
2. built-in modules

파이썬에서 제공하는 공식 모듈 목록
    _abc
    _ast
    _bisect
    _blake2
    _codecs
    _collections
    _datetime
    _elementtree
    _functools
    _heapq
    _imp
    _io
    _locale
    _md5
    ...
3. sys.path

모듈의 검색 경로를 지정하는 문자열 리스트
프로그램 시작시 환경 변수 PYTHONPATH와 설치 종속 기본값으로 초기화되며 
path[0]은 main.py파일이 속한 디렉터리이다
sys.path 리스트를 목적에 맞게 자유롭게 수정할 수 있다
import를 시도하면 목록의 순서대로 시도 후 sys.path에서도 발견하지 못하면
ModuleNotFoundError를 리턴한다

기본적인 순서는 다음과 같다
  • 현재 디렉토리
  • 환경변수 PYTHONPATH에 지정된 경로
  • Python이 설치된 경로 및 그 밑의 라이브러리 경로
  /home/sjh/WorkSpace/test/venv
  /home/sjh/WorkSpace/test
  /usr/lib/python37.zip
  /usr/lib/python3.7
  /usr/lib/python3.7/lib-dynload
  /home/sjh/WorkSpace/test/venv/lib/python3.7/site-packages
  /home/sjh/WorkSpace/test/venv/lib/python3.7/site-packages/setuptools-40.8.0-py3.7.egg
  /home/sjh/WorkSpace/test/venv/lib/python3.7/site-packages/pip-19.0.3-py3.7.egg

sys.modules과 sys.path의 차이점

  • sys.modules
    한번이라도 import된 모듈을 {이름:객체}페어로 저장하는 dictionary
    import module의 캐시로서 기능한다

  • sys.path
    모듈과 패키지의 검색 위치를 제공하는 단순한 절대경로들의 리스트
    문자열과 바이트열만 있어야 한다

sys를 import해야 할 경우

파이썬에서 모든것은 객체이며 내부적으로 object class를 상속받고 있다
모든 객체의 원형인 object class는 __builtins__객체에 built-in 모듈들을 가지고 있으므로
모든 객체들은 built-in 함수인 __import__를 사용할 수 있으며 이를 통해
파이썬 인터프리터에 내장되어있는 built-in module인 sys를 import할 수 있다

package

점으로 구분된 모듈 이름을 써서 파이썬의 모듈 이름 공간을 구조화하는 방법
여러 파일로 나뉘어져 있는 module들을 디렉토리화 해서 묶는다

__init__.py

__init__파일은 __all__ 객체만 정의된 파이썬 파일이다

all 객체는 * 기호를 사용하여 import할 경우 리턴될 모듈들을 스트링값의 리스트로 지정한다
패키지 내의 파일에는 __init__.py파일이 존재하는것이 권장 되나
python3.3 이후 부터는 필수는 아니다

절대 경로와 상대 경로의 차이

  • 절대경로
    대상 파일과 경로에 상관 없이 항상 동일한 경로
    최상위 디렉토리에서부터 시작해서 .로 하위 디렉토리, 파일에 접근하는 방식이다
    일반적으로 절대경로를 사용하나 경로가 길어진다는 단점이 있다

  • 상대경로
    절대경로와 달리 현재 파일의 위치를 기준으로 하여 시작하는 경로
    현재 디렉토리 : .
    상위 디렉토리 : ..
    위 경우 상대 경로를 사용할 수 있지만 경로가 직관적이지 않고 파일 위치가 변경되면
    경로 또한 바꿔주어야 한다는 점에서 절대 경로가 권장된다

__package__ 문제

파이썬 인터프리터는 __name__객체와 __package___ 객체를 통해
디렉토리에서 자신의 위치를 파악하는데 만약 파일이 직접 실행 되었을 경우에는
__name__ 객체가 __main__, __package__객체는 None으로 설정 되고
import되었을 때는 올바른 자신의 위치를 가진 __name__ 객체와 __package__ 객체를 갖게 된다

이 때 생기는 문제는 __package__ 객체에 값이 할당되지 않으면 파이썬 인터프리터가
현재 파일이 속한 디렉터리를 최상위 디렉터리로 인식한다는 점에서 발생한다

위 실행 환경을 바탕으로 생각하면 main.py 파일을 직접 실행할 경우에는 모든 모듈에 접근할 수 있으나
최상위 디렉토리에 속하지 않은 module을 실행할 경우 에는 다른 모듈에 접근할 수 없는데
import module은 실행된 파일이 속한 디렉터리를 최상위 디렉터리로 인식하기 때문이다

그러나 main.py를 실행하여 각 상호 의존적인 모듈을 import하면 문제없이 실행 된다

적용

  • testmodule4에서 testmodule3에 접근 하려면?
    절대경로 : from testpackage3.testmodule3 import *
    상대경로 : from ..testmodule3 import *

0개의 댓글