지금까지 우리는 주로 Colab 노트북 환경에서 코드를 작성하고 즉시 결과를 확인하는 방식으로 파이썬을 배워왔습니다. 노트북 환경은 탐색적 데이터 분석이나 학습 과정에는 매우 훌륭하지만, 실제 연구나 프로젝트에서는 다음과 같은 요구사항이 생길 수 있습니다.
자동화: 매번 노트북을 열어 코드를 실행하는 것이 아니라, 특정 분석 작업을 자동으로 또는 명령 한 줄로 실행하고 싶을 때 (예: 매일 새로운 데이터를 받아 균형점을 계산하고 보고).
코드 재사용: 우리가 만든 유용한 함수들(예: find_equilibrium)을 이번 분석뿐만 아니라, 다른 프로젝트나 다른 스크립트에서도 쉽게 가져다 쓰고 싶을 때.
협업 및 관리: 코드가 점점 길고 복잡해질 때, 여러 개의 파일로 기능별로 나누어 관리하고 다른 사람들과 협업하고 싶을 때.
이러한 요구사항을 해결하기 위해 파이썬에서는 명령줄 스크립트(Command-line Script) 와 모듈(Module)/패키지(Package) 라는 개념을 사용합니다. 오늘은 이 두 가지 개념에 대해 간단히 맛보는 시간을 갖겠습니다. (이 내용은 고급 과정이므로, 지금 당장 완벽히 이해하지 않아도 괜찮습니다!)
1. 명령줄에서 파이썬 실행하기 (argparse 소개)
우리가 작성한 파이썬 코드를 .py 라는 확장자로 저장하면, 터미널(명령 프롬프트, PowerShell 등) 환경에서 python 파일이름.py 명령으로 실행할 수 있습니다. 이것을 파이썬 스크립트라고 부릅니다.
그런데 스크립트를 실행할 때마다 수요/공급 함수의 파라미터(a, b, c, d) 값을 코드 내부에서 직접 수정하는 것은 번거롭습니다. 스크립트를 실행하는 시점에 이 값들을 외부에서 전달해주면 훨씬 유연하겠죠? 이때 사용하는 것이 명령줄 인자(Command-line Argument) 이며, 파이썬에서는 argparse 라는 표준 라이브러리를 통해 이를 쉽게 처리할 수 있습니다.
argparse 사용 예시 (sd_analyzer.py 가상 스크립트)
만약 아래와 같은 내용으로 sd_analyzer.py 파일을 만들었다고 가정해 봅시다. (Colab에서는 아래 코드를 직접 실행하기보다, 이런 .py 파일을 만들 수 있다는 개념을 이해하는 것이 중요합니다.)
파일명: sd_analyzer.py (실제 파일로 저장해야 함)
import argparse
# --- S&D 관련 함수 정의 (또는 다른 파일에서 import) ---
# (이 부분은 설명을 위해 간단히 다시 정의합니다. 실제로는 import 사용 권장)
def quantity_demanded(price, a, b):
if b <= 0: return None
q_d = a - b * price
return max(0, q_d)
def quantity_supplied(price, c, d):
if d <= 0: return None
q_s = c + d * price
return max(0, q_s)
def find_equilibrium(a, b, c, d):
if b <= 0 or d <= 0 or (b + d) == 0: return None
p_star = (a - c) / (b + d)
if p_star < 0: return None
q_star = quantity_demanded(p_star, a, b)
# if q_star < 0: return None # 필요시 추가
return p_star, q_star
# --- 함수 정의 끝 ---
# 1. ArgumentParser 객체 생성
parser = argparse.ArgumentParser(description='선형 수요/공급 모델의 균형점을 계산합니다.')
# 2. 명령줄 인자 정의 (--a, --b, --c, --d 라는 이름으로 인자를 받음)
# type=float : 입력값을 실수로 처리
# required=True : 필수 인자임을 명시
# help='...' : 도움말 메시지
parser.add_argument('--a', type=float, required=True, help='수요 함수 절편 (Qd = a - bP)')
parser.add_argument('--b', type=float, required=True, help='수요 함수 기울기 절대값 (Qd = a - bP)')
parser.add_argument('--c', type=float, required=True, help='공급 함수 절편 (Qs = c + dP)')
parser.add_argument('--d', type=float, required=True, help='공급 함수 기울기 (Qs = c + dP)')
# 3. 명령줄 인자 파싱(분석)
args = parser.parse_args()
# 4. 파싱된 인자를 사용하여 균형점 계산 함수 호출
# args.a, args.b 등으로 접근 가능
equilibrium_point = find_equilibrium(args.a, args.b, args.c, args.d)
# 5. 결과 출력
if equilibrium_point:
p_eq, q_eq = equilibrium_point
print(f"--- 계산 결과 ---")
print(f"수요 함수: Qd = {args.a} - {args.b}P")
print(f"공급 함수: Qs = {args.c} + {args.d}P")
print(f"균형 가격(P*): {p_eq:.2f}")
print(f"균형 거래량(Q*): {q_eq:.2f}")
else:
print("오류: 균형점을 계산할 수 없습니다. 파라미터를 확인하세요.")
스크립트 실행 방법 (터미널에서):
위 sd_analyzer.py 파일이 저장된 디렉토리에서, 터미널을 열고 다음과 같이 명령어를 입력하면 됩니다.
python sd_analyzer.py --a 100 --b 2 --c 10 --d 3
이렇게 하면 --a 뒤의 100이 args.a로, --b 뒤의 2가 args.b로 전달되어 코드가 실행되고 결과가 터미널에 출력됩니다. 파라미터 값을 바꿔가며 스크립트를 쉽게 재실행할 수 있습니다.
(Colab/Jupyter 환경에서는) 위 파이썬 코드를 직접 실행하면 argparse가 명령줄 인자를 찾지 못해 오류가 발생합니다. Colab에서 명령줄 인자를 테스트하려면 특별한 방법(sys.argv 조작 등)이 필요하지만, 여기서는 “파이썬 스크립트를 만들고 명령줄에서 인자를 받아 실행할 수 있다” 는 개념을 이해하는 것이 중요합니다.
2. 나만의 코드 모음 만들기 (모듈과 패키지 기초)
우리가 작성한 함수들(quantity_demanded, quantity_supplied, find_equilibrium)은 다른 분석에서도 유용하게 쓰일 수 있습니다. 이 함수들을 별도의 파이썬 파일(.py)로 저장해두면, 다른 노트북이나 스크립트에서 가져와서(import) 재사용할 수 있습니다. 이렇게 재사용 가능한 코드(함수, 클래스, 변수 등)를 담고 있는 .py 파일을 모듈(Module) 이라고 부릅니다.
모듈 만들기 (Colab에서 %%writefile 사용):
Colab에서는 %%writefile 파일이름.py 이라는 특별한 명령(Cell Magic)을 코드 셀 맨 위에 써서 해당 셀의 내용을 파이썬 파일로 저장할 수 있습니다.
%%writefile market_models.py# 이 셀의 내용은 market_models.py 파일로 저장됩니다."""시장 수요, 공급, 균형점 계산 관련 함수들을 모아놓은 모듈"""def quantity_demanded(price, a, b):"""선형 수요 함수 Qd = a - bP 를 계산합니다."""if b <=0:# print("오류: 수요 곡선 기울기(b)는 양수여야 합니다.") # 모듈에서는 print보다 오류 발생 권장raiseValueError("수요 곡선 기울기(b)는 양수여야 합니다.") q_d = a - b * pricereturnmax(0, q_d)def quantity_supplied(price, c, d):"""선형 공급 함수 Qs = c + dP 를 계산합니다."""if d <=0:raiseValueError("공급 곡선 기울기(d)는 양수여야 합니다.") q_s = c + d * pricereturnmax(0, q_s)def find_equilibrium(a, b, c, d):"""선형 수요/공급 함수의 균형 가격(P*)과 균형 거래량(Q*)을 계산하여 튜플로 반환합니다."""if b <=0or d <=0:raiseValueError("수요/공급 곡선 기울기(b, d)는 양수여야 합니다.")if (b + d) ==0:raiseValueError("수요와 공급 곡선 기울기 합이 0입니다. 평행선.") p_star = (a - c) / (b + d)if p_star <0:# print("균형 가격이 음수입니다.") # 실제 균형 없음return (None, None) # 음수 가격 대신 None 반환 고려# 균형 거래량 계산 q_star = quantity_demanded(p_star, a, b) # 같은 모듈 내 함수 호출# if q_star < 0: q_star = 0 # 필요시 음수 거래량 0 처리return p_star, q_star# 모듈로 만들 때는 아래와 같은 직접 실행 코드는 보통 if __name__ == "__main__": 블록 안에 넣습니다.# (이 부분은 모듈로 사용될 때는 실행되지 않음)if__name__=="__main__":print("market_models 모듈이 직접 실행되었습니다. (테스트용)")# 간단한 테스트 코드 a_test, b_test =100, 1 c_test, d_test =20, 2 p_eq, q_eq = find_equilibrium(a_test, b_test, c_test, d_test)if p_eq isnotNone:print(f"테스트 균형점: P*={p_eq:.2f}, Q*={q_eq:.2f}")
Writing market_models.py
위 셀을 실행하면 Colab의 현재 작업 디렉토리에 market_models.py 파일이 생성됩니다. (왼쪽 파일 탐색기 탭에서 확인 가능)
모듈 가져와서 사용하기 (import):
이제 다른 코드 셀이나 다른 노트북에서 이 market_models.py 모듈을 가져와서 그 안에 정의된 함수들을 사용할 수 있습니다.
# 1. 모듈 전체를 import 하기import market_models# 함수 호출 시 모듈 이름을 앞에 붙여야 함eq1 = market_models.find_equilibrium(a=100, b=2, c=10, d=3)if eq1[0] isnotNone:print(f"(import 모듈 전체) 균형 가격: {eq1[0]:.2f}, 균형 거래량: {eq1[1]:.2f}")# 2. 모듈에서 특정 함수만 import 하기from market_models import quantity_demanded, find_equilibrium# 함수 이름으로 직접 호출 가능qd1 = quantity_demanded(price=15, a=100, b=2)eq2 = find_equilibrium(a=150, b=3, c=30, d=2)print(f"(from import) 가격 15일 때 수요량: {qd1}")if eq2[0] isnotNone:print(f"(from import) 균형 가격: {eq2[0]:.2f}, 균형 거래량: {eq2[1]:.2f}")# 3. 모듈에 별명(alias) 붙여서 사용하기 (자주 사용됨!)import market_models as mm # mm 이라는 별명으로 사용eq3 = mm.find_equilibrium(a=50, b=1, c=5, d=1)if eq3[0] isnotNone:print(f"(import as 별명) 균형 가격: {eq3[0]:.2f}, 균형 거래량: {eq3[1]:.2f}")
(import 모듈 전체) 균형 가격: 18.00, 균형 거래량: 64.00
(from import) 가격 15일 때 수요량: 70
(from import) 균형 가격: 24.00, 균형 거래량: 78.00
(import as 별명) 균형 가격: 22.50, 균형 거래량: 27.50
3. 코드를 더욱 체계적으로: 패키지(Package) 구성하기
이전 섹션에서 우리는 관련된 함수들을 하나의 .py 파일(모듈)로 묶어 재사용하는 방법을 배웠습니다 (market_models.py 예시). 프로젝트의 규모가 커지면, 단순히 모듈 하나만으로는 부족할 수 있습니다. 예를 들어, 시장 모델 자체를 정의하는 함수들, 그 모델을 분석하는 함수들, 분석 결과를 시각화하는 함수들 등 기능별로 코드를 더 세분화하여 관리하고 싶을 수 있습니다.
이럴 때 사용하는 것이 바로 패키지(Package) 입니다. 패키지는 관련된 모듈들을 담는 디렉토리(폴더) 라고 생각할 수 있습니다. 패키지를 사용하면 다음과 같은 장점이 있습니다.
계층적 구조: 관련 기능별로 하위 디렉토리를 만들어 코드를 더욱 체계적으로 구성할 수 있습니다 (예: 모델 정의는 models 폴더, 분석 코드는 analysis 폴더).
이름 충돌 방지 (Namespace Management): 서로 다른 패키지나 모듈 안에 같은 이름의 함수가 있더라도, 패키지명.모듈명.함수명 형태로 구분하여 사용할 수 있으므로 이름 충돌을 피할 수 있습니다.
배포 및 공유 용이: 잘 만들어진 패키지는 다른 사람들과 쉽게 공유하고 설치하여 사용할 수 있습니다 (오늘 다루지는 않지만 pip install ... 과 관련됩니다).
패키지 구성의 핵심: __init__.py 파일
파이썬이 어떤 디렉토리를 패키지로 인식하게 하려면, 그 디렉토리 안에 __init__.py 라는 이름의 특별한 파일이 반드시 있어야 합니다. 이 파일은 비어 있어도 괜찮지만, 존재 자체가 “이 디렉토리는 파이썬 패키지입니다” 라고 알려주는 역할을 합니다. (패키지 초기화 코드를 넣을 수도 있습니다.)
예시: 수요/공급 분석 코드를 패키지로 구성하기
Week 6 실습 2에서는 수요 또는 공급 변화 후 새로운 균형점을 계산하고 원래 균형과 비교하는 분석을 했습니다. 이 분석 과정을 가상의 econo_analyzer 라는 패키지로 구성해 봅시다.
패키지 구조:
econo_analyzer/ <-- 최상위 패키지 디렉토리
|-- __init__.py <-- 이 디렉토리가 패키지임을 알림
|-- models/ <-- 모델 정의 관련 모듈들을 담을 하위 디렉토리(서브 패키지)
| |-- __init__.py <-- 이 디렉토리도 패키지임을 알림
| |-- market.py <-- 수요(Qd), 공급(Qs), 균형점(find_equilibrium) 함수 정의
|-- analysis/ <-- 분석 관련 모듈들을 담을 하위 디렉토리(서브 패키지)
| |-- __init__.py <-- 이 디렉토리도 패키지임을 알림
| |-- shifts.py <-- 수요/공급 변화(shift) 분석 함수 정의
|-- utils/ <-- (선택 사항) 보조 기능 모듈 (예: 시각화)
| |-- __init__.py
| |-- plotting.py
각 파일의 역할 (가상):
econo_analyzer/__init__.py: econo_analyzer 를 패키지로 만듭니다. (비어 있어도 됨)
econo_analyzer/models/__init__.py: models 를 서브 패키지로 만듭니다.
econo_analyzer/models/market.py: 이전 보충 자료의 market_models.py 내용과 같이 quantity_demanded, quantity_supplied, find_equilibrium 함수를 포함합니다.
econo_analyzer/analysis/__init__.py: analysis 를 서브 패키지로 만듭니다.
econo_analyzer/analysis/shifts.py: (실습 2 관련) 수요 또는 공급 변화 전후의 파라미터를 받아 두 균형점을 계산하고 비교/분석하는 함수 (예: analyze_demand_shift, analyze_supply_shift 또는 compare_equilibria)를 포함합니다.
econo_analyzer/utils/plotting.py: (선택) 수요/공급 곡선 및 균형점을 그리는 함수를 분리하여 포함할 수 있습니다.
Colab에서 패키지 구조 만들기 (명령어 사용):
Colab 노트북 환경에서는 실제 디렉토리와 파일을 직접 만들기 어렵기 때문에, 터미널 명령어(앞에 !를 붙여 실행)와 %%writefile 매직 명령어를 사용하여 가상으로 구조를 만들어 볼 수 있습니다.
1단계: 디렉토리 생성
!mkdir -p econo_analyzer/models # econo_analyzer 디렉토리와 그 하위 models 디렉토리 생성 (-p 옵션)
!mkdir -p econo_analyzer/analysis # econo_analyzer 하위 analysis 디렉토리 생성
# !mkdir -p econo_analyzer/utils # 필요하다면 utils 디렉토리도 생성
%%writefile econo_analyzer/models/market.py# 이 셀의 내용은 econo_analyzer/models/market.py 파일로 저장됩니다."""시장 수요, 공급, 균형점 계산 관련 함수들을 모아놓은 모듈"""def quantity_demanded(price, a, b):"""선형 수요 함수 Qd = a - bP 를 계산합니다."""if b <=0: raiseValueError("수요 곡선 기울기(b)는 양수여야 합니다.") q_d = a - b * pricereturnmax(0, q_d)def quantity_supplied(price, c, d):"""선형 공급 함수 Qs = c + dP 를 계산합니다."""if d <=0: raiseValueError("공급 곡선 기울기(d)는 양수여야 합니다.") q_s = c + d * pricereturnmax(0, q_s)def find_equilibrium(a, b, c, d):"""선형 수요/공급 함수의 균형 가격(P*)과 균형 거래량(Q*)을 계산하여 튜플로 반환합니다."""if b <=0or d <=0: raiseValueError("수요/공급 곡선 기울기(b, d)는 양수여야 합니다.")if (b + d) ==0: raiseValueError("수요와 공급 곡선 기울기 합이 0입니다. 평행선.") p_star = (a - c) / (b + d)if p_star <0: return (None, None) # 음수 가격 q_star = quantity_demanded(p_star, a, b)return p_star, q_starprint("econo_analyzer.models.market 모듈 로드됨") # 모듈 로드 확인용 (선택 사항)
Writing econo_analyzer/models/market.py
shifts.py 파일 작성 (실습 2 분석 기능 구현):
%%writefile econo_analyzer/analysis/shifts.py# 이 셀의 내용은 econo_analyzer/analysis/shifts.py 파일로 저장됩니다."""수요 또는 공급 변화 분석 함수 모듈"""# 다른 모듈의 함수를 사용하기 위해 importfrom econo_analyzer.models import market # 같은 패키지 내 models 폴더의 market 모듈 importdef compare_equilibria(params_old, params_new):""" 변화 전후의 파라미터 딕셔너리를 받아 두 균형점을 계산하고 비교 결과를 반환합니다. 파라미터 딕셔너리 예시: {'a': 150, 'b': 3, 'c': 30, 'd': 2} """# 원래 균형점 계산 p_old, q_old = market.find_equilibrium(params_old['a'], params_old['b'], params_old['c'], params_old['d'])# 새로운 균형점 계산 p_new, q_new = market.find_equilibrium(params_new['a'], params_new['b'], params_new['c'], params_new['d']) results = {"old_equilibrium": (p_old, q_old),"new_equilibrium": (p_new, q_new), }# 변화 설명 추가 (선택 사항)if p_old isnotNoneand p_new isnotNone:if p_new > p_old: results["price_change"] ="상승"elif p_new < p_old: results["price_change"] ="하락"else: results["price_change"] ="변동 없음"else: results["price_change"] ="비교 불가"if q_old isnotNoneand q_new isnotNone:if q_new > q_old: results["quantity_change"] ="증가"elif q_new < q_old: results["quantity_change"] ="감소"else: results["quantity_change"] ="변동 없음"else: results["quantity_change"] ="비교 불가"return resultsprint("econo_analyzer.analysis.shifts 모듈 로드됨") # 모듈 로드 확인용 (선택 사항)
Writing econo_analyzer/analysis/shifts.py
패키지 사용하기:
이제 위에서 만든 패키지의 함수들을 import 해서 사용할 수 있습니다.
# 패키지 및 모듈 importfrom econo_analyzer.models import marketfrom econo_analyzer.analysis import shifts# 실습 2-1의 파라미터 설정params_initial = {'a': 150, 'b': 3, 'c': 30, 'd': 2} # 원래 상태params_demand_decrease = {'a': 120, 'b': 3, 'c': 30, 'd': 2} # 수요 감소 후 상태# 변화 분석 함수 호출comparison_result = shifts.compare_equilibria(params_initial, params_demand_decrease)# 결과 출력print("\n--- 수요 감소 효과 분석 결과 (패키지 사용) ---")p_old, q_old = comparison_result["old_equilibrium"]p_new, q_new = comparison_result["new_equilibrium"]price_change_desc = comparison_result["price_change"]quantity_change_desc = comparison_result["quantity_change"]print(f"원래 균형점: P*={p_old:.2f}, Q*={q_old:.2f}")print(f"새로운 균형점: P*={p_new:.2f}, Q*={q_new:.2f}")print(f"균형 가격 변화: {price_change_desc}")print(f"균형 거래량 변화: {quantity_change_desc}")# market 모듈의 함수도 직접 사용 가능p_test =20qd_test = market.quantity_demanded(p_test, params_initial['a'], params_initial['b'])print(f"\n(market 모듈 직접 호출) 가격 {p_test}에서 수요량: {qd_test}")
econo_analyzer.models.market 모듈 로드됨
econo_analyzer.analysis.shifts 모듈 로드됨
--- 수요 감소 효과 분석 결과 (패키지 사용) ---
원래 균형점: P*=24.00, Q*=78.00
새로운 균형점: P*=18.00, Q*=66.00
균형 가격 변화: 하락
균형 거래량 변화: 감소
(market 모듈 직접 호출) 가격 20에서 수요량: 90
정리:
패키지는 여러 모듈들을 체계적으로 구성하여 더 크고 복잡한 프로젝트를 관리할 수 있게 해주는 중요한 개념입니다. 비록 Colab 환경에서는 실제 로컬 환경처럼 패키지를 다루기에는 제약이 따르지만, !mkdir, !touch, %%writefile 등을 이용해 그 구조와 사용법을 경험해 볼 수 있습니다. 기능별로 코드를 분리하고(market.py, shifts.py), __init__.py를 통해 디렉토리를 패키지로 인식시키며, import 구문을 통해 필요한 기능을 가져다 쓰는 이 방식은 여러분이 앞으로 더 큰 규모의 파이썬 프로젝트를 접하게 될 때 매우 유용할 것입니다.
정리:
argparse는 파이썬 스크립트를 명령줄에서 더 유연하게 실행할 수 있게 도와주고, 모듈과 패키지는 코드를 체계적으로 구성하고 재사용성을 높여 더 크고 복잡한 프로젝트를 가능하게 합니다. 노트북 환경을 넘어서 실제 파이썬 프로그램을 개발할 때 매우 중요한 개념들이니, 이런 것이 있다는 것을 기억해두시면 좋겠습니다.