상세 컨텐츠

본문 제목

[Python] 파이썬 모듈/패키지 파해치기 - 모듈 생성하기/불러오기/상대경로/절대경로

개발 이야기/Python

by 리치윈드 - windFlex 2022. 6. 25. 23:42

본문

반응형

파이썬 모듈과 패키지에 대해여 자세히 알아보자.

모듈 : 함수들이 뭉쳐진 하나의 .py 파일 
패키지 : 여러 개의 모듈을 그룹화한 묶음
라이브러리 : 패키지의 모음을 그룹화 

 

[목차]

  • 파이썬 모듈 만들기
  • 파이썬 모듈 불러오기 (상대경로, 절대경로, 환경변수 등록)
  • 파이썬 모듈 실행 : __name__의 의미
  • 패키지와의 관계

 

 

파이썬 모듈 (Python Module) 

 

모든 python 파일 (*.py)는 모듈이며, 각 모듈은 `import`를 통해서 모듈을 추가 할 수 있다. 또한 모듈 안의 모든 함수와 개체 또한 모듈로 볼 수 있다. 

import 모듈이름

예를 들어, 다음과 같은 코드를 `calc.py`로 저장한 경우를 가정하자.

# calc.py
def add(a,b):
	return a+b

 

모듈 불러오기

이 경우 다음과 같이 모듈을 추가할 수 있다. 

import calc
print( calc.add(10, 20) )
`import calc.py`와 같이 확장자는 포함하지 않음에 주의한다.

또한 다음과 같이 `from`을 사용할 수 있다. 

from calc import add
print( add(10, 20) )

 

다른위치의 모듈 불러오기

지금까지는 동일한 디렉토리에 존재하는 모듈을 불러왔으나, 모듈파일이 다른위치에 있으면 어떻게 불러올 수 있을까?

 

1) 상대경로 사용 (Relative Path)

상대경로는 별다른 설정 없이 다른 위치에 있는 모듈을 바로 추가 할 수 있는 방법이다. 그러나, 그 모듈의 위치가 하위 디렉토리 혹은 부모/형제 디렉토리에 위치하는 모듈 정도에 적용하는 것이 적당하다. 제 3의 독립적인 위치에 적용하는 것은 어려울뿐만 아니라 에러 발생가능성이 높아 진다.  

  • 하위 디렉토리이 있는 모듈을 추가하는 경우
form child.dir.path import module_name
  • 상위 디렉토리/형제 디렉토리에 있는 모듈 파일을 추가하는 경우
from ..parent.sibling.path import module_name

 

2) sys.path 추가 하기 (sys.path.append)

 

 sys.path.append(모듈을 저장한 디렉터리)

사실상, 하위디렉터리가 아닌 경우 가장 많이 사용되는 module 추가 방법이다. `sys.path.append( path_dir )`을 사용하여 python 이 구동되는 기본 path를 추가하는 방법이다. 

다음과 같이 `sys.path`에 python의 기본 구동 디렉토리가 등록되어 있으며, path이 구동할 때 찾는 path는 해당 디렉터리들에서 우선적으로 찾게 된다.  `append( path_name )`을 사용하여 `sys.path`를 추가해 주는 것이다. 

import sys
print(sys.path)

사실 상, 다음에 소개되는 OS차원의 환경변수인 `$PYTHONPATH`에 추가해주는 것을 python 내부환경에서 처리해 주는 것과 동일하다. 

 

3) 환경변수 (PYTHONPATH)

 

OS 차원에서 환경변수 `PYTHONPATH`를 등록해 주는 방법이 있다. 

(Windows)

set PYTHONPATH=C:\python-project\path\my_module\

(Linux)

$ export PYTHONPATH='/root/python-projects/path/'

 

if __name__=='__main__'의 의미

python의 모든 개체는 내부적으로 사용하거나, 초기화에 사용되는 던더(Double Underscore)들이 포함되어 있다. 대표적으로 class의 생성자인 `__init__()`등이 여기에 해당한다. 이중에서, 일반개체외에 최상인 개체인 모듈자체에는 `__name__`이 포함되어 있다. 다음과 같이 실행해 보도록 하자.

print( dir() )
# ....(생략) ...  , __name__ , ....(생략)
print( __name__ )
# '__main__'

`dir()`을 통해서 현재 최상위 개체에 로딩되어 있는 개체와 변수를 확인 할 수 있다. ( `__name__`이 이미 존재한다. ) `print(__name__)`으로 변수 내용을 출력해 보면, 아마도 대다수의 환경에서는 `__main__`이 출력 될 것이다. `__main__`은 현재 실행되는 위치의 이름을 저장하고 있는 변수이다. 즉, 현재 실행되는 모듈의 환경에 `main`에서 호출되었다는 것이다.

그렇다면, `main`이외의 다른것이 있다는 것일까?

그렇다. __name__의 내용은 크게 2종류 이다. 

  • 최상위 모듈에서 실행  : `__main__`
  • 참조되는 모듈에서 실행 : `모듈 이름`

실험을 위해서, 다음과 같이 `my_module`모듈을 생성하고 my_module.py에 저장하자.

그리고 다른 파일에서 import 해보도록하자. 

# my_module.py
def add(a,b):
    return a+b

print('my_module : ' , __name__)
import my_module
print('load a my module')
어떤 결과가 출력 되었는가?
my_module :  my_module
load a my module
응? 프린트 문장이 2개? 왜?

위 실험 결과에서 이해할 수 있듯이, python은 내부적으로 `import`를 하는 시점에 module 파일이 실행된다. 즉, `my_module`이라는 모듈이 실행될 때 `print`문이 실행 된 것이다. 

그렇다면, 다시 이런 걱정이 될 것이다. 

"음.... 그렇다면, `import` 할 때마다 import 내부 실행 결과가 구동되면 어떻게 하지????" 

위와 같은 문제를 해결하기 위해서, 오직 module 자체를 실행할 때만 동작하는 코드루틴을 만들기 위해서, `if __name__=="__main__" ` 이라는 구문을 사용하는 것다. 이제 우리는 내부 동작을 확실히 이해 할 수 있다. import 할 때는 실행하지 말고, module 자체에서 실행할 때만  ( __name__ == '__main__' ) 구동 하도록 조건문을 걸어준 것이다. 

 

파이썬  패키지 (Python Package) 

파이썬 패키지는 모듈들의 묶음이다. 여러 개의 module을 포함하는 디렉터리 구조와 `__init__.py`로 구성 되어 있다. 

 

모듈과 패키지의 관계도. # 출처: pythonstudy.xyz

 

 

[ 연 재 ]  (다음편에서...)

 

 

반응형

관련글 더보기

댓글 영역