[참조]
- 공학자를 위한 Python, 조정래, 2022: 2.5 모듈과 패키지
https://wikidocs.net/14596 - Dookie Kim, Python: From Beginning to Application, 2022 [PDF]
프로그램을 작성하게 되면 거의 대부분 외부 라이브러리의 활용이 필요하다.
프로그램의 규모가 커짐에 따라 자신이 직접 코딩한 소스도 분할하여야 한다.
여기에 대응하는 개념이 모듈(module)과 패키지(package)이다.
목차
| 항목 | 모듈 (Module) | 패키지 (Package) | 파일 분할 (File Splitting) |
|---|---|---|---|
| 정의 | 하나의 Python 파일 (.py)로 구성된 코드 묶음 | 여러 모듈(.py 파일)로 구성된 디렉토리 | 기능별로 파일을 나누어 관리하는 방법 |
| 사용 예시 | import math |
import numpy.linalg |
import BeamFunctions |
| 특징 | 단일 기능 또는 연관 함수 제공 | 구조적이며 계층적으로 구성 | 코드를 읽기 쉽게 분할함 |
| 디렉토리 필요 여부 | 필요 없음 | 필요 (하위 폴더 구조) | 선택 사항 |
(1) 모듈
1) 모듈의 정의
- 모듈(module)은 재사용할 목적으로 작성된 파이썬 소스 파일이다.
- import 문으로 로딩하여 사용한다.
- 예를 들어 os 모듈은 os.py 라는 파일로 작성되어 있으며 사용시에서는 import os 등으로 로딩한다.
(예시)
import os
os.environ
os.chdir() # 디렉토리 변경(change dir)
os.getcwd() # 현재 디렉토리 가져오기(get current working dir)
os.system('dir')
os.system('cls')
os.mkdir()
os.path.dirname(path) # Return the dir name of pathname path.
os.path.basename(path) # Return the base name of pathname path.
os.rmdir() # remove an empty dir
os.remove() # remove a file.
os.unlink()
os.rename(src,dst)
(예시)
def cls():
import os
os.system('cls')
cls()
여기서 파이썬에서는 모든 것이 객체이고, 모든 객체들에 대해 이름(name)을 붙여 모아 둔 공간(space)을 namespace라 한다.
2) 모듈의 호출 방법
- 여러가지 import 문의 변형이 가능하다.
(예시 1)
from mysolver import * # 모든 함수 import
xNewton = solve_by_newton(func, der, 10)
(예시 2)
from mysolver import solve_by_newton, tol # 일부 함수 import
xNewton = solve_by_newton(func, der, 10)
print(tol)
(예시 3)
import mysolver as solver # 이름을 solver로 변경하여 import
xNewton = solver.solve_by_newton(func, der, 10)
(예시 4)
from mysolver import solve_by_newton as solve # 일부 함수를 변경된 이름으로 import
xNewton = solve(func, der, 10)
(비교) import vs from
import(가져오기)는 전체 모듈(module)을 가져오는 데 사용되며,
from(불러오기)은 모듈(module)에서 특정 개체(object)를 가져오거나
모듈의 모든 개체(object)를 현재 네임스페이스(namespace)로 가져오는 데 사용된다.
3) 모듈 테스트
- 모듈을 작성한 후 테스트를 수행하기 위해 스크립트로 실행될 수 있다.
- 이 경우 모듈 하단에 __name__ 속성이 '__main__'인지 확인하여 실행시키는 것이 일반적인 방법이다.
- 다음은 Python 공식 튜토리얼에 소개된 fibo 모듈이다.
-
(예시) fibo.py
# fibo.py def fib(n): a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a + b print() if __name__ == "__main__": import sys fib(int(sys.argv[1]))fibo.py가 있는 디렉토리에서 다음과 같이 모듈을 실행한다.
# 실행 예시 # > python fibo.py 100 # 또는 import fibo fibo.fib(100) # 출력: 1 1 2 3 5 8 13 21 34 55 89
4) dir(모듈)
- 내장함수 dir(module)은 모듈에서 정의하고 있는 변수, 함수 등등을 출력해 준다.
- 다음은 앞서 작성한 fibo 모듈에 대해 임포트 후 dir(fibo)를 적용한 예이다.
(예시)
>>> dir(fibo)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fib']
(2) 패키지
- 패키지(package)는 모듈을 디렉토리 구조로 묽어 놓은 것이다.
예를 들어 os 모듈은 os.py라는 파일로 존재하지만 대표적 수치 패키지인 NumPy는 numpy라는 폴더 내에서 여러 모듈이 존재한다.
패키지 라이브러리를 사용하는 것은 점(.; dot)으로 하위폴더 내에 있는 모듈을 import 할 수있다.
예를 들어 sound/effects/echo.py에 echofilter(...)라는 함수를 사용하려면 다음과 같다.
(Note: 하위 폴더나 하위 함수를 호출하기 위해 점(.; dot)을 사용한다.
(예시 1)
import sound.effects.echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
(예시 2)
from sound.effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)
(예시 3)
from sound.effects.echo import echofilter
echofilter(input, output, delay=0.7, atten=4)
(예시 4)
from sound.effects.echo import *
echofilter(input, output, delay=0.7, atten=4)
부 패키지(sub-package) 자체를 임포트할 수도 있다.
(예시 5)
from sound.effects import *
echo.echofilter(input, output, delay=0.7, atten=4)
(3) 파일 분할
- 하나의 파일로 만들면 파일이 크고 내용이 복잡하다.
- 이를 함수들을 구분하여 별도의 파일로 만든 후 import를 사용하여 불러 들일 수 있다.
(예시: 메인) beam.py
import BeamFunctions as beam
m1 = beam.ElementMass(m, L1)
k1 = beam.ElementStiffness(E, I, L1)
M0 = beam.Assemble(M0, m1, 1, 2)
(예시: 서브) BeamFunctions.py
def ElementMass(m, L):
# 질량 행렬 계산 코드
pass
def ElementStiffness(E, I, L):
# 강성 행렬 계산 코드
pass
def Assemble(K, k, i, j):
# 조립 함수
pass