본문으로 건너뛰기
혼자 쓰던 스크립트를 여럿이 부르는 서버로

생성 수정

IBM * 레드햇 AX 과정 · 3강

혼자 쓰던 스크립트를 여럿이 부르는 서버로

2026년 5월 4일(월) ~ 5월 8일(금)

이 강의 문제풀이 — 배운 내용을 주관식 문답으로 확인해보세요.풀어보기 →

이 장을 다 읽으면

  1. 스크립트와 서버의 차이를 "누가 진입점을 잡는가"로 설명할 수 있다.
  2. 라이브러리와 프레임워크를 세 가지 축(진입점·흐름 제어·입출력)으로 구별할 수 있다.
  3. 어떤 것이 디스크에 있고 어떤 것이 메모리에 있는지 판별할 수 있다.
  4. 데이터(Data)와 밸류(Value)를 코드 한 줄에서 짚어낼 수 있다.
  5. 클래스·인스턴스·객체를 각각 정의하고, 셋이 같은 것을 다르게 부르는 지점을 설명할 수 있다.
  6. 저장/불러오기와 업로드/다운로드가 왜 다른 축인지 말할 수 있다.
  7. 리터럴이 무엇이고 왜 "리터럴이 구조를 만든다"고 하는지 설명할 수 있다.
  8. 생성형 AI와 에이전틱 AI, 어플과 에이전트를 "누가 판단하는가"로 나눌 수 있다.
  9. .venv를 만들고 FastAPI 앱을 띄워 포스트맨으로 응답을 확인할 수 있다.

0. 이 장의 판별 축

새 용어를 만나면 비유를 찾기 전에 아래 축 중 어디에 꽂히는지부터 정하세요. 비유부터 잡으면 경계가 흐려집니다. 축을 먼저 잡으면 아직 안 배운 것도 추론됩니다.

#축왼쪽 (0)오른쪽 (1)이 축으로 갈리는 것
1누가 부르는가혼자 쓴다 (내가 진입점)여럿이 요청한다 (프레임워크가 부른다)스크립트 ↔ 서버 / 라이브러리 ↔ 프레임워크
2어디에 있는가디스크 (영구·구상)메모리 (휘발·추상)클래스 ↔ 인스턴스 / DATA__ ↔ value
3크기가 얼마인가집합 (거시)최소 단위 (미시)데이터 ↔ 밸류
4스스로 판단하는가수동형 (시킨 것만)추론형 (스스로 계획)어플 ↔ 에이전트 / 생성형 ↔ 에이전틱
5어떤 경계를 넘는가내 컴퓨터 안인터넷 너머저장/불러오기 ↔ 업로드/다운로드

축 1이 이 장의 중심입니다. 이 주에 손으로 한 일 전부가 축 1을 왼쪽에서 오른쪽으로 옮기는 작업이었습니다.

⭐ 이 주를 한 문장으로 "혼자 쓰는 파이썬 스크립트"를 "누구나 요청하면 응답하는 웹 서버"로 바꾼 것.

이 축들이 3주차에서 어떻게 확장되는가

지금 잡아둔 다섯 축은 다음 장에서 이름을 바꾸어 다시 나옵니다. 미리 표시해 둡니다.

이 장의 축3주차에서의 확장
축 1 누가 부르는가제어의 역전(IoC) 이라는 정식 이름을 얻습니다. 그리고 DIP·DI·전략 패턴·포트&어댑터가 전부 이 축의 다른 이름임을 보게 됩니다. 옆에 동기/비동기(기다리는가) 축이 추가됩니다.
축 2 어디에 있는가메모리가 다시 세 구역(Method Area / Heap / Stack)으로 쪼개집니다. 디스크·메모리 축 위에 프로덕트·프로젝트·프로그램·프로세스(4P) 가 배치됩니다.
축 3 크기가 얼마인가스칼라 → 벡터 → 매트릭스 → 텐서 라는 차원의 축으로 자랍니다. 동시에 "객체 = 속성 + 기능 / 개체 = 객체 − 기능 / 함수 = 객체 − 속성" 이라는 뺄셈식이 등장합니다.
축 4 스스로 판단하는가추론형 AI를 조직 차원에서 붙들어 두는 체계 — AI 하네스로 이어집니다.
축 5 어떤 경계를 넘는가이동에 직렬화(Serialization) / 역직렬화(Deserialization) 라는 정식 이름이 붙고, 데이터가 계층을 건널 때마다 형태가 바뀌는 물류 계층으로 확장됩니다.

1. 컴퓨터는 어떻게 생겼는가

1.1 파스칼린에서 클래스까지 — 왜 계보를 보는가

우리가 이번 주에 class James: 라고 쓰게 되는데, 클래스는 처음부터 있던 게 아닙니다. 이 사실을 알고 있으면 "왜 굳이 클래스로 감싸야 하지?"라는 질문에 스스로 답할 수 있습니다.

1642년 — 파스칼린(Pascaline) 블레즈 파스칼이 만든 세계 최초의 상업화된 기계식 계산기입니다. 핵심 발명은 톱니바퀴의 자동 올림(Carry) 메커니즘이었습니다. 9에서 하나를 더하면 옆 자리로 1이 넘어가는 그 동작을, 사람이 아니라 톱니가 하게 만든 것입니다. 오늘날 디지털 회로가 하는 '올림(캐리)' 연산의 원형이 여기 있습니다.

1970년 — Pascal 언어에는 클래스가 없었다 파스칼을 기려 이름 붙인 프로그래밍 언어 Pascal이 나왔을 때, 이 언어는 구조적 프로그래밍(Structured Programming) 언어였습니다. 값들을 묶는 RECORD는 있었지만, 기능을 함께 묶는 클래스는 없었습니다.

시기무엇이 있었나무엇이 없었나
1970 PascalRECORD (값의 묶음)클래스, 메서드
애플 리사 개발기Object Pascal 등장—
1995 델파이현대적 클래스 정립—

애플 리사(Lisa) 개발 과정에서 Object Pascal이 등장했고, 1995년 델파이(Delphi)에서 오늘날 우리가 아는 형태의 클래스가 정립되었습니다. 그리고 PascalCase라는 명칭이 이 계보에서 나왔습니다.

표기법(Naming Convention) 세 가지

이름모양파이썬에서 쓰는 곳
PascalCaseTitanicQaApp클래스 이름 — class James, class Walter, FastAPI
camelCasetitanicQaApp자바스크립트 변수·함수
snake_casetitanic_qa_app파이썬 함수·변수 — read_titanic_data, get_data
UPPER_SNAKE_CSV_PATH파이썬 상수

⚠️ 표기법은 문법이 아니라 약속입니다. 어겨도 실행은 됩니다. 하지만 코드를 읽는 사람(그리고 AI)이 "대문자로 시작하니 클래스겠구나"를 즉시 판단하지 못하게 됩니다. 우리가 쓰는 _CSV_PATH의 대문자와 언더바는 "이건 프로그램 내내 안 바뀌는 값" 이라는 신호입니다.

계보에서 얻을 것: 값만 묶는 단계(RECORD)에서, 값과 기능을 함께 묶는 단계(클래스)로 넘어가는 데 25년이 걸렸습니다. 이 주에 우리가 class James: 안에 _CSV_PATH(값)와 get_data()(기능)를 함께 넣는 것이 바로 그 25년의 결론입니다.

1.2 폰 노이만 구조 — 컴퓨터의 기본 설계도

폰 노이만 구조(von Neumann Architecture) = CPU + 메모리 + 프로그램

지금 쓰는 거의 모든 컴퓨터가 이 구조입니다.

        ┌──────────┐              ┌──────────────────────┐
        │   CPU    │◀──── 버스 ───▶│       메모리          │
        │ (연산)    │   (Bus)      │  프로그램 + 데이터     │
        └──────────┘              └──────────────────────┘
                                            ▲
                                            │ 불러오기 / 저장
                                            ▼
                                  ┌──────────────────────┐
                                  │  스토리지 (디스크)     │
                                  └──────────────────────┘
  • CPU — 실제로 계산하는 곳
  • 메모리(RAM) — 지금 쓰는 프로그램과 데이터가 올라와 있는 곳
  • 버스(Bus) — CPU와 메모리를 연결하는 통로

핵심이자 약점: 메모리 안에서 프로그램(명령어) 영역과 데이터 영역에 물리적 구분이 없습니다. 그래서 명령어와 데이터가 같은 버스를 공유하고, 동시에 접근할 수 없습니다.

이것이 폰 노이만 병목(von Neumann Bottleneck) 입니다. 아무리 CPU가 빨라져도 통로가 하나라 한 번에 하나씩만 지나갈 수 있습니다. 외나무다리입니다.

왜 이걸 이 주에 배우는가: 우리가 곧 uvicorn으로 서버를 띄우면, 여러 사람의 요청이 동시에 들어옵니다. "동시에 여러 개를 처리한다"는 말이 실제로는 무엇을 뜻하는지 — 외나무다리를 어떻게 나눠 쓰느냐의 문제라는 것을 — 알아두면 3주차의 동기/비동기가 훨씬 쉽습니다.

1.3 메모리와 스토리지 — 실존하는 공간과 실존하지 않는 공간

축 2가 여기서 시작됩니다. 앞으로 배울 거의 모든 개념이 이 둘 중 하나에 속합니다.

메모리 (Memory / RAM)스토리지 (Storage / Disk·SSD)
성격임시영구
전원이 꺼지면사라진다남는다
속도매우 빠름느림
용량작음큼
1GB당 가격비쌈쌈
비유작업 책상창고
성격(추상/구상)실존하지 않는 공간 (추상)실존하는 공간 (구상)

마지막 줄이 이 절의 핵심 문장입니다.

  • 스토리지는 실존하는 공간입니다. 전원을 꺼도 그 자리에 파일이 그대로 있습니다. 탐색기를 열면 눈에 보입니다. 구상(具象) 입니다.
  • 메모리는 실존하지 않는 공간입니다. 전원을 끄면 흔적도 없습니다. 어느 폴더를 열어도 "지금 메모리에 있는 것"은 보이지 않습니다. 추상(抽象) 입니다.

⭐ 이 구분은 나중에 "클래스는 디스크에, 인스턴스는 메모리에"로 그대로 이어집니다. 눈에 보이는 것(파일)은 설계도이고, 눈에 안 보이는 것(실행 중인 것)이 실체라는 역설이 여기서 나옵니다.

⚠️ 자주 하는 혼동: "메모리가 부족하다"와 "저장 공간이 부족하다"는 완전히 다른 말입니다.

  • 메모리 부족 → 프로그램이 느려지거나 강제 종료됨
  • 저장 공간 부족 → 파일을 새로 만들 수 없음

1.4 방향에는 이름이 있다 — 저장/불러오기 vs 업로드/다운로드

데이터가 움직이는 방향마다 정해진 이름이 있습니다. 축 5입니다.

방향이름넘는 경계
메모리 → 디스크저장 (Save)내 컴퓨터 안
디스크 → 메모리불러오기 (Load)내 컴퓨터 안
내 컴퓨터 → 남의 서버업로드 (Upload)네트워크
남의 서버 → 내 컴퓨터다운로드 (Download)네트워크
  • 저장(Save): 작업 중인 내용을 영구 보관하는 것. 책상에서 창고로.
  • 불러오기(Load): 보관된 내용을 꺼내와 작업 준비를 하는 것. 창고에서 책상으로.

⚠️ 가장 흔한 오해 — "디스크에서 메모리로 가져오는 걸 업로드라고 부른다" ❌ 아닙니다. 그건 불러오기(Load) 입니다. 업로드/다운로드는 인터넷(네트워크)이라는 경계를 넘을 때만 쓰는 말입니다.

두 쌍은 축이 다릅니다.

  • 저장/불러오기 → 내 컴퓨터 안에서의 위아래 (책상 ↔ 창고)
  • 업로드/다운로드 → 내 컴퓨터와 바깥 세계 사이 (나 ↔ 서버)

기억법: up/down은 "나보다 위에 있는 서버"를 기준으로 잡은 방향입니다. 서버로 올리면 up, 서버에서 내리면 down. 반면 save/load에는 위아래가 없습니다. 내 책상과 내 창고 사이의 왕복일 뿐입니다.

앞으로 다시 만납니다 3주차에서 저장/불러오기는 직렬화(Serialization) / 역직렬화(Deserialization) 라는 정식 이름을 얻습니다. 메모리 위의 입체적인 객체를 디스크에 넣기 위해 일렬로 늘어뜨리는 것이 직렬화입니다.

1.5 논리와 논증 — 규칙과 결과물

같은 주에 나온 개념인데, 지금은 사소해 보이지만 이 장 전체의 형태를 설명해 줍니다.

논리 (Logic)논증 (Argument)
무엇인가올바른 추론의 원리·규칙그 규칙으로 근거를 들어 주장을 펼친 실제 결과물
비유문법문장
존재 형태추상 · 변하지 않음구상 · 매번 다름

이 구분이 왜 프로그래밍 교재에 나오는가 하면, 같은 모양이 계속 반복되기 때문입니다.

규칙 (추상 · 디스크)결과물 (구상 · 메모리)
논리 (Logic)논증 (Argument)
문법문장
프로그래밍 언어의 문법내가 쓴 코드
클래스인스턴스
클래스 안의 DATA__인스턴스 안의 value
설계도지어진 집

축 2가 철학의 언어로 한 번, 프로그래밍의 언어로 한 번 나온 것입니다. 새 개념을 만나면 "이건 규칙 쪽인가 결과물 쪽인가"만 물어도 절반은 정리됩니다.


2. 데이터와 밸류 — 집합과 최소 단위

2.1 정의

축 3입니다. 둘 다 "값"이라고 뭉뚱그려 부르기 쉽지만 크기가 다릅니다.

  • 데이터 (Data) — [정보를 담은 것]인데, [특정 목적을 위해 수집된 사실·수치의 집합체]라는 점에서 밸류와 구별된다. 거시적·구조적 개념.
    • 비유: 재료가 가득 담긴 장바구니 혹은 냉장고
  • 밸류 (Value) — [정보를 담은 것]인데, [데이터 안을 구성하는 하나하나의 구체적인 값]이라는 점에서 데이터와 구별된다. 더 이상 쪼개기 어려운 최소 단위.
    • 비유: 장바구니 안의 당근 1개, 계란 1알
데이터 (Data)밸류 (Value)
크기집합최소 단위
관점거시적미시적
구조있음 (표·행·열)없음 (그냥 값)
비유장바구니당근 1개

2.2 코드에서 짚어내기

df = pd.read_csv(_CSV_PATH)   # df 전체 → 데이터
age = df.at[1, 'Age']         # 22 라는 숫자 → 밸류
조각무엇인가
df (데이터프레임 전체)데이터 — 표 하나 통째
df['Age'] (한 열 전체)데이터 — 여전히 집합
df.at[1, 'Age'] 로 꺼낸 22밸류 — 칸 하나에 적힌 값

데이터프레임(DataFrame) 구조 용어

용어뜻타이타닉에서
데이터프레임행과 열로 된 2차원 표승객 목록 전체
행 (Row)가로 한 줄승객 한 명
열 (Column)세로 한 줄Age, Sex 같은 항목
셀 (Cell)행과 열이 만나는 칸2번 승객의 나이 칸
밸류 (Value)그 칸에 실제로 적힌 것38.0

💡 df.at[1, 'Age'] 를 읽는 법: at은 "그 자리에". [행 번호, 열 이름] 순서입니다. 1은 두 번째 행입니다. 파이썬은 0부터 셉니다.

2.3 DATA__(설계) vs value(실체)

축 2(디스크/메모리)와 축 3(집합/단위)이 여기서 만납니다.

클래스 안의 DATA__인스턴스 안의 value
어디에디스크 (.py 파일 안)메모리 (실행 중)
무엇설계도상의 이름표실제로 채워진 값
비유설문지의 빈칸 이름: ____그 빈칸에 적어 넣은 James
변하는가안 변함인스턴스마다 다름

흐름은 이렇습니다.

디스크의 클래스 (구조·이름표)
        │  실행 시 읽어옴
        ▼
메모리의 인스턴스 (구조 + 실제 값)
        │  값만 바꿔가며 사용
        ▼
원본 클래스는 그대로 남아 있음

⭐ 원본 클래스는 절대 변하지 않습니다. 쿠키 틀로 쿠키를 백 개 찍어도 틀은 그대로인 것과 같습니다. 그래서 인스턴스를 몇 개를 만들든, 설계도는 안전합니다.

2.4 리터럴 — 기계어처럼 쓰는 것

리터럴 (Literal) — [코드에 쓰는 표기]인데, [값 자체를 글자 그대로 적어 둔 것]이라는 점에서 변수와 구별된다.

literal은 "문자 그대로의"라는 뜻입니다. 어원 자체가 정의입니다.

왜 이런 게 필요한가 컴퓨터가 실제로 이해하는 것은 기계어(0과 1)입니다. 그런데 사람이 기계어로 직접 쓰는 것은 사실상 불가능합니다. 그래서 사람이 읽을 수 있는 글자로, 기계어처럼 못 박아 쓰는 표기법을 만들었습니다. 그게 리터럴입니다.

리터럴의 종류

종류예뜻
정수 리터럴42숫자 42 그 자체
실수 리터럴3.14, 71.2833소수 그 자체
문자열 리터럴"Titanic-Dataset.csv"따옴표 안의 글자 그대로
불리언 리터럴True, False참·거짓
None 리터럴None값이 없음
리스트 리터럴[1, 2, 3]대괄호로 만든 목록
딕셔너리 리터럴{"role": "user"}중괄호로 만든 짝

2.5 리터럴이 구조를 만든다

이 한 줄이 이 절의 결론입니다.

{"message": "FAST API 초기화 성공", "docs": "/docs"}

여기서 {, }, ", :, , 는 전부 리터럴 표기입니다. 그런데 이 표기를 지키는 순간, 이것은 그냥 글자가 아니라 딕셔너리라는 자료구조가 됩니다. 그리고 이 구조가 그대로 밖으로 나가면 JSON이 됩니다.

글자 그대로의 표기 (리터럴)
        ↓  약속된 기호를 지키면
자료구조 (딕셔너리 · 리스트)
        ↓  밖으로 내보내면
데이터 형식 (JSON)

⭐ 리터럴이 구조를 만듭니다. 괄호와 따옴표와 콜론은 장식이 아닙니다. 그 기호들의 배치가 곧 구조의 정의입니다.

⚠️ JSON에서 자주 나는 오류 다섯 가지 — 전부 리터럴 표기를 어긴 것입니다.

  1. 따옴표 빠짐 2. 쉼표 빠짐 3. 중괄호 짝 안 맞음 4. 콜론 대신 다른 기호 5. true와 "true" 혼동

true는 참·거짓 값이고 "true"는 그냥 글자 네 개입니다. 완전히 다릅니다.

2.6 리터럴 · 변수 · 함수 · 인자 · 인스턴스 — 한 줄에서 다 구분하기

df = pd.read_csv(_CSV_PATH)

이 짧은 한 줄에 다섯 종류가 들어 있습니다.

조각무엇인가설명
df변수이자 인스턴스결과물이 담기는 그릇. DataFrame 클래스의 인스턴스. 리터럴이 아님
=대입 연산자"같다"가 아니라 "넣는다"
pd모듈 별칭import pandas as pd 로 붙인 이름
read_csv함수데이터를 읽어오는 동작
_CSV_PATH인자(변수)함수에 전달하는 식재료(값)
"Titanic-Dataset.csv"리터럴_CSV_PATH 안에 담겨 있는, 글자 그대로 적힌 값

💡 파이썬에서는 함수 실행 결과물뿐 아니라 함수 그 자체도 하나의 객체로 취급됩니다. read_csv라는 이름 자체를 변수에 담아 넘길 수도 있습니다. (이 성질이 3주차 전략 패턴의 바탕이 됩니다.)

2.7 사람은 왼쪽부터, 기계는 오른쪽부터

같은 한 줄을 사람과 기계가 반대 방향으로 읽습니다.

df = pd.read_csv(_CSV_PATH)
  • 사람의 읽기 — 왼쪽부터. "df는 CSV를 읽은 결과다."
  • 기계의 읽기 — 오른쪽부터. "먼저 pd.read_csv(_CSV_PATH) 를 실행해서 결과를 만들고, 그 결과에 df 라는 이름표를 붙인다."
사람기계
읽는 방향왼쪽 → 오른쪽오른쪽 → 왼쪽
= 의 뜻"~는 ~이다""오른쪽을 계산해 왼쪽에 넣어라"

이게 왜 중요한가 — 이 한 줄이 설명됩니다.

x = x + 1

수학이라면 성립하지 않는 식입니다(0 = 1이 되어버립니다). 그러나 코드에서는 성립합니다. 오른쪽의 x + 1을 먼저 계산한 뒤, 그 결과를 왼쪽 x에 다시 넣기 때문입니다.

⚠️ "같다"는 == 입니다. = 는 대입, == 는 비교. 이 둘을 섞는 것이 초보자의 가장 흔한 오타입니다.


3. 클래스 · 인스턴스 · 객체

3.1 세 단어를 각각 정의하기

이번 주 코드에서 이 세 단어가 한꺼번에 나옵니다.

app = FastAPI()      # FastAPI → 클래스,  app → 인스턴스
w   = Walter()       # Walter  → 클래스,  w   → 인스턴스
james = James()      # James   → 클래스,  james → 인스턴스

정의를 유(類, 상위 범주) + 종차(種差, 그 안에서의 차이) 형식으로 씁니다.

  • 클래스 (Class) — [객체를 만들기 위한 정의]인데, [실체가 아니라 실체를 찍어내기 위한 설계도]라는 점에서 인스턴스와 구별된다.
  • 인스턴스 (Instance) — [메모리에 만들어진 실체]인데, [어떤 클래스에서 태어났는지 소속이 지정된다]는 점에서 그냥 값과 구별된다.
  • 객체 (Object) — [데이터(속성)와 기능(메서드)을 하나로 묶은 실체]인데, [소속보다 독립된 물건 그 자체라는 점을 강조한다]는 점에서 인스턴스와 구별된다.

3.2 클래스는 디스크, 인스턴스는 메모리

축 2가 여기서 가장 선명하게 쓰입니다.

클래스 (Class)인스턴스 (Instance)
어디에디스크메모리 (RAM)
성격정적(Static)동적(Dynamic)
형태.py 파일로 저장된 설계도 문서실행 시 만들어진 실체
프로그램이 꺼져 있을 때존재함존재하지 않음
프로그램이 끝나면남음사라짐
개수하나몇 개든 만들 수 있음
[ 디스크 ]                       [ 메모리 ]
 james.py                          james = James()   ← 인스턴스 1
   class James:      ── 실행 ──▶    j2    = James()   ← 인스턴스 2
     ...                            j3    = James()   ← 인스턴스 3
   (설계도 하나)                     (실체 여럿)

⭐ 설계도는 하나, 실체는 여럿. 그리고 실체가 아무리 많아져도 설계도는 그대로입니다.

3.3 영미권의 대표적인 세 가지 비유

이 개념은 영어권 교재에서 거의 항상 셋 중 하나로 설명됩니다.

비유클래스인스턴스 / 객체
Blueprint & House설계도실제로 지어진 집
Cookie Cutter & Cookies쿠키 틀찍어낸 쿠키들
Car Design & Actual Car자동차 도면도로를 달리는 실제 차

세 비유가 공통으로 말하는 것: 설계도는 먹을 수도, 살 수도, 탈 수도 없습니다. 실체가 되어야 쓸 수 있습니다.

⚠️ 다만 비유는 기억 보조용입니다. 판별은 축으로 하세요 — "이건 디스크에 있나 메모리에 있나."

3.4 "클래스 + 인스턴스 = 오브젝트"

이 수업에서 반복해서 나오는 등식입니다. 의미는 이렇습니다.

클래스 (정의 · 능력)  +  인스턴스 (메모리 · 몸체)  =  오브젝트 (살아 움직이는 완성체)

"능력(클래스/정의)"이 "몸체(인스턴스/메모리)"를 얻어 실제로 살아 움직이는 완성체(객체)가 된다 — 역동적인 관점입니다.

  • 설계도만 있으면 → 아무 일도 일어나지 않습니다.
  • 메모리 자리만 있으면 → 무엇을 할지 모릅니다.
  • 둘이 합쳐져야 → 요청을 받고 응답하는 살아 있는 무언가가 됩니다.

app = FastAPI() 한 줄이 하는 일이 정확히 이것입니다. 남이 만든 설계도(FastAPI 클래스)로 내 메모리에 앱 한 채를 짓는 일입니다.

3.5 객체와 인스턴스는 같은 대상, 다른 관점

이 둘은 같은 것을 가리키면서 부르는 각도가 다릅니다.

부르는 말강조하는 것말투
객체 (Object)독립적인 물건 그 자체"저기 데이터 덩어리가 있네"
인스턴스 (Instance)어떤 설계도에서 태어났는지 소속"저건 Walter 클래스의 인스턴스야"

같은 사람을 두고 "저 사람"이라고 부르는 것과 "김씨 집안 사람"이라고 부르는 것의 차이입니다. 대상은 같고 관점만 다릅니다.

3.6 오브젝트와 서브젝트

Object의 반대말은 Instance가 아니라 Subject입니다. 이걸 알면 헷갈릴 일이 줄어듭니다.

서브젝트 (Subject · 주체)오브젝트 (Object · 객체)
성격능동적수동적
하는 일행위를 하는 쪽행위를 당하는 쪽
예사용자, 실행 중인 프로그램, 알림을 보내는 주체다루어지는 데이터, 조작되는 파일
문장에서"내가 파일을 연다"의 '나'"내가 파일을 연다"의 '파일'

어원이 이미 다 말해줍니다.

단어어원뜻
Objectob-(향하여) + jacere(던지다)던져진 것 — 다루어지는 대상
Subjectsub-(아래) + jacere(던지다)아래에 놓인 것 — 밑에 깔린 근거, 주어

영어 문법의 주어(Subject)와 목적어(Object) 가 같은 단어인 것은 우연이 아닙니다. 같은 발상에서 나왔습니다.

⚠️ 참고: 일반적인 객체지향 프로그래밍(OOP)에서 '오브젝트'는 이 주체/객체 대비보다는 '독립된 실체' 그 자체를 뜻하는 쪽으로 씁니다. 문맥을 봐야 합니다.

앞으로 다시 만납니다 3주차에서 객체는 뺄셈식으로 다시 정의됩니다. 객체 = 속성 + 기능 / 개체(Entity) = 객체 − 기능 / 함수(Function) = 객체 − 속성 그리고 "개체"와 "객체"라는, 발음까지 비슷한 두 단어를 갈라내게 됩니다.

3.7 프로그래밍의 '객체'와 AI의 '모델'

같은 파이썬 코드 안에 둘 다 등장하는데, 층이 다릅니다.

객체 (Object)모델 (Model)
무엇인가소프트웨어를 구성하는 부품·그릇데이터 학습으로 알아낸 패턴·규칙·수학적 공식
비유백지 상태의 신입사원신입사원이 데이터를 보고 깨우친 '노하우'
만드는 법클래스를 설계해서데이터를 학습시켜서
하는 일데이터를 저장하고 실행예측·분류·생성

둘의 결합: 파이썬에서 인공지능을 만들 때, '객체'라는 그릇 안에 '모델(학습된 지식)'이 담겨서 작동합니다.

model = RandomForestClassifier()   # 객체(그릇)를 하나 만들고
model.fit(X, y)                    # 그 안에 학습된 지식(모델)을 채운다

⚠️ "모델"이라는 단어는 세 군데서 다른 뜻으로 쓰입니다. 미리 표시해 둡니다.

맥락'모델'의 뜻
머신러닝학습된 패턴·가중치
데이터베이스테이블 설계(데이터 모델링)
MVC 아키텍처메모리 위의 도메인 객체

3주차에서 세 번째 뜻을 정면으로 다룹니다.

3.8 파인튜닝 — 모델을 내 목적에 맞게 고쳐 쓰기

이 주에 처음 이름이 나옵니다.

파인튜닝 (Fine-tuning) — [모델을 학습시키는 방법]인데, [처음부터 학습시키는 대신, 이미 학습된 모델에 특정 목적의 데이터를 추가로 학습시킨다]는 점에서 사전학습(Pre-training)과 구별된다.

  • 사전 학습 모델 (Pre-trained Model): 방대한 데이터를 이미 학습해 둔 모델
  • 파인튜닝: 그 모델을 가져와 특정 목적이나 데이터셋에 맞춰 추가 학습시키는 과정

비유: 일반 상식을 가진 '대학생' 에게 우리 회사의 '전문 업무' 를 가르쳐 '전문가' 로 만드는 과정.

파이썬 관점: 기존 모델의 거대한 '밸류(가중치)' 들을 내 목적에 맞게 재학습시켜 업데이트하는 코딩 작업입니다. (transformers, PyTorch 등을 씁니다.)

⭐ 축 3이 여기서 다시 쓰입니다. 모델의 알맹이는 결국 수억 개의 밸류(가중치) 입니다. 학습이란 그 밸류들을 조금씩 고쳐 나가는 일입니다. 개념이 아니라 숫자입니다.

모델을 내 목적에 맞추는 세 가지 방법 — 비용 순서대로 놓으면 판단이 쉬워집니다.

방법무엇을 바꾸나비용언제 쓰나
프롬프팅아무것도 안 바꿈. 질문만 잘함없음대부분의 경우 — 여기부터 시작
RAG모델은 그대로, 참고 자료를 붙임중간최신 정보·사내 문서가 필요할 때
파인튜닝모델의 가중치 자체높음말투·출력 형식·전문 도메인을 고정하고 싶을 때

⚠️ 순서를 건너뛰지 마세요. 프롬프트로 해결되는 문제에 파인튜닝을 쓰면 시간과 비용만 듭니다.


4. 스크립트에서 서버로

4.1 지금 상태 진단하기

전환을 하려면 지금 무엇인지부터 정확히 말해야 합니다.

질문 프롬프트

@apps/titanic 이것을 라이브러리 시스템에서 프레임워크 시스템으로 전환하려고 해.
fastapi 로 전환하는 방법을 알려줘.

진단 결과: apps/titanic 은 스크립트 + 클래스 모듈 형태였습니다. james.py 의 if __name__ == "__main__" 에서 Walter 를 직접 호출하는 흐름 — 이것이 전형적인 "내가 진입점을 잡는" 라이브러리·스크립트 스타일입니다.

# 전환 전 — 내가 진입점을 잡는 구조
if __name__ == "__main__":
    w = Walter()
    print(w.get_data())

💡 if __name__ == "__main__" 은 무슨 뜻인가 파이썬은 직접 실행되는 파일의 __name__ 변수에 "__main__" 이라는 값을 넣습니다. 반면 import 되어 불려온 파일에는 그 파일의 모듈 이름이 들어갑니다. 그래서 이 조건문은 "이 파일이 직접 실행됐을 때만 아래를 실행해라" 라는 뜻입니다.

4.2 라이브러리와 프레임워크 — 세 축으로 갈린다

축 1의 정식 이름표입니다.

라이브러리 (Library)프레임워크 (Framework)
진입점내가 잡음 — python james.py프레임워크가 잡음 — uvicorn 이 ASGI 앱을 띄움
흐름 제어내 코드가 순서대로 실행요청이 올 때 프레임워크가 내 핸들러를 호출
입출력(I/O)print · 파일 직접 읽기HTTP 요청/응답, 보통 JSON
성격기능 중심구조 중심
비유도구상자 — 내가 골라 씀작업장 — 정해진 틀 안에 내 코드를 넣음
한 줄내가 부른다나를 부른다
예pandas, requestsFastAPI, Django, Next.js

⭐ "Don't call us, we'll call you." 할리우드 오디션에서 나온 말이 그대로 프레임워크의 원리 이름이 되었습니다. 이걸 정식으로는 제어의 역전(IoC, Inversion of Control) 이라고 부릅니다.

⚠️ React는 라이브러리, Next.js는 프레임워크입니다. 같은 자바스크립트 생태계 안에서도 갈립니다. React 자체는 UI를 그리는 도구 모음이고, Next.js는 폴더 구조·라우팅·빌드까지 정해주는 틀입니다.

앞으로 다시 만납니다 3주차에서 IoC는 DIP(의존성 역전 원칙), DI(의존성 주입), 전략 패턴, 포트&어댑터 와 전부 같은 한 가지를 가리키는 다른 이름들로 정리됩니다.

4.3 엔트리 포인트 — 진입점

엔트리 포인트 (Entry Point · 진입점) — [프로그램이 시작되는 위치]인데, [제어권이 운영체제로부터 프로그램으로 넘어오는 가장 첫 번째 지점]이라는 점에서 그냥 첫 줄과 구별된다.

프로그램이 수만 줄이라도, 컴퓨터는 "여기서부터 읽기 시작해!" 라고 약속된 입구가 있어야 합니다. 웹 프로젝트에서는 앱을 구동하는 최상단 스크립트(예: main.py) 가 진입점이 됩니다.

전환의 본질은 진입점의 이사입니다.

전환 전 (스크립트)전환 후 (서버)
실행 명령python james.pyuvicorn main:app --reload
진입점을 잡는 주체나 (파일을 직접 실행)uvicorn (ASGI 서버)
시작 지점파일 맨 위 → if __name__ == "__main__"main 모듈 안의 app 객체
언제 코드가 도는가실행하는 그 순간 한 번요청이 들어올 때마다

💡 ASGI가 뭔가요 ASGI (Asynchronous Server Gateway Interface) — 파이썬 웹 앱과 웹 서버가 서로 대화하기 위한 규격입니다.

  • uvicorn = ASGI 서버 (요청을 받는 쪽)
  • FastAPI = ASGI 앱 (요청을 처리하는 쪽)

규격이 정해져 있기 때문에, uvicorn 대신 다른 ASGI 서버를 써도 앱 코드는 그대로 둘 수 있습니다. 규격이 곧 갈아끼울 수 있는 자유를 만듭니다.

4.4 식당으로 보는 전체 그림

이번 주의 모든 도구가 식당 하나에 대응됩니다. 먼저 대응표를 통째로 보고, 단계별로 다시 봅니다.

요소식당에서코드에서
스크립트혼자 냉장고 열어 혼자 먹기python james.py
FastAPI식당 시스템 (주문 창구·메뉴 체계)app = FastAPI()
uvicorn문을 열어 손님을 받는 것uvicorn main:app --reload
라우트(경로)메뉴판의 메뉴 이름@app.get("/titanic/data")
.venv이 식당 전용 주방 도구 세트가상환경
requirements.txt주방 도구 목록 (레시피 북)의존성 목록
class주방장 설계도class James:
인스턴스고용된 주방장 한 명James()
메서드"요리해줘" 라고 시키는 것.get_data()
JSON 응답손님에게 나가는 음식return df.to_dict(...)

1단계: 처음 상태 — "혼자 요리해서 혼자 먹기"

처음에 james.py 는 그냥 파이썬 스크립트였습니다.

python james.py 실행
→ CSV 파일 읽기
→ 결과 출력
끝.

이건 마치 내가 직접 냉장고 열어서, 재료 꺼내서, 혼자 먹는 것입니다. 나만 먹을 수 있고, 다른 사람은 못 받습니다.

2단계: 문제 — "다른 사람도 이 데이터를 쓰고 싶다"

웹사이트나 앱을 만들면, 여러 사람이 동시에 데이터를 요청합니다. 그러면 "혼자 먹기" 방식으로는 안 됩니다. 식당처럼 바꿔야 합니다.

손님(앱/브라우저) → 주문(요청) → 주방(서버) → 음식(데이터) 반환

3단계: FastAPI — "식당 차리기"

FastAPI가 바로 그 식당 시스템입니다.

  • 손님이 /titanic/data 로 주문하면
  • 주방(james.py)에서 CSV를 꺼내서
  • 음식(JSON 데이터)을 돌려줍니다
@app.get("/titanic/data")   # ← 이 주소로 주문 오면
def read_titanic_data():
    james = James()          # ← 주방장(James) 부르고
    df = james.get_data()    # ← 요리(데이터 읽기) 시키고
    return df.to_dict(...)   # ← 손님한테 전달

💡 @app.get(...) 앞의 @ 는 데코레이터(Decorator) 입니다. "이 아래 함수를, 이 주소로 GET 요청이 오면 실행할 함수로 등록해 둬라"는 표시입니다. 내가 이 함수를 부르는 게 아니라, 등록만 해두고 프레임워크가 부릅니다. 축 1이 코드 한 줄에 드러난 자리입니다.

4단계: uvicorn — "식당 문 열기"

FastAPI로 식당을 설계했어도, 문을 열어야 손님이 올 수 있습니다.

uvicorn main:app --reload

이게 바로 "식당 오픈!" 선언입니다. 이걸 실행하면 http://127.0.0.1:8000 이라는 주소로 누구나 요청을 보낼 수 있게 됩니다.

5단계: .venv — "식당 전용 주방 도구"

.venv 는 이 식당만을 위한 주방 도구 세트입니다.

다른 식당(프로젝트)이랑 도구가 섞이면 버전이 충돌나서 오류가 생길 수 있습니다. 그래서 프로젝트마다 따로 관리합니다.

6단계: requirements.txt — "주방 도구 목록"

다른 컴퓨터(또는 서버)에서도 똑같이 실행하려면, 어떤 도구가 필요한지 목록이 있어야 합니다.

pip freeze > requirements.txt    # 목록 저장
pip install -r requirements.txt  # 다른 컴퓨터에서 그대로 설치

마치 "우리 식당 레시피 북" 같은 것입니다.

7단계: james.py 구조 — "주방장 클래스"

class James:
    def get_data(self):
        df = pd.read_csv(_CSV_PATH)   # CSV 읽고
        return df.iloc[[1]]           # 데이터 반환

class 는 주방장을 설계도로 만든 것입니다.

  • James() → 주방장 한 명을 고용하는 것 (인스턴스 생성)
  • .get_data() → "요리해줘" 라고 시키는 것 (메서드 호출)

전체 흐름 한눈에 보기

브라우저 / 앱
    ↓ (http://127.0.0.1:8000/titanic/data 요청)
uvicorn    ← 문지기. 요청을 받아서 FastAPI로 넘김
    ↓
main.py    ← 어느 주소로 왔는지 보고 담당 함수 연결
    ↓
james.py   ← 실제로 CSV 읽어서 데이터 준비
    ↓
JSON 응답  ← 브라우저 / 앱에 데이터 전달

4.5 전환 순서 여섯 단계

에버노트에 정리된 실제 전환 절차입니다. 순서를 지키세요.

1. 의존성 추가 fastapi, uvicorn[standard] 를 추가합니다(기존 pandas 등은 유지).

2. ASGI 앱을 진입점으로 app = FastAPI() 를 한 번만 만들고 uvicorn main:app --reload 로 실행합니다. if __name__ == "__main__" 는 개발용 CLI로만 남기거나 제거합니다.

3. Walter 를 서비스 레이어로

  • 반환값을 DataFrame 대신 list[dict] 또는 Pydantic 모델로 바꿉니다.
  • 경로는 상대 경로가 cwd에 따라 깨지므로 다음을 씁니다.
Path(__file__).resolve().parent / "Titanic-Dataset.csv"

⚠️ 왜 상대 경로가 깨지는가 상대 경로("./Titanic-Dataset.csv")는 실행하는 디렉터리(cwd, Current Working Directory) 기준으로 해석됩니다. 같은 코드라도 어느 폴더에서 실행했느냐에 따라 파일을 못 찾습니다. 반면 __file__ 은 그 코드 파일 자신의 위치입니다. 어디서 실행하든 안 흔들립니다.

⚠️ 왜 DataFrame 을 그대로 반환하면 안 되는가 HTTP는 텍스트(JSON 등)만 나를 수 있습니다. DataFrame 은 메모리 위의 파이썬 객체입니다. 메모리 객체를 밖으로 보내려면 글자로 펴는 과정이 반드시 필요합니다. (3주차의 직렬화입니다.)

4. 라우트에서만 외부와 대화 GET /data → 내부에서 Walter 호출 → JSON 응답. Pydantic 모델로 정의하면 /docs 까지 자동 생성됩니다.

5. 구조 나누기

폴더·파일담당여기 넣으면 안 되는 것
routers/HTTP만 — 주소·메서드·상태코드비즈니스 로직
services/도메인 로직 — 실제 계산·판단HTTP 관련 코드
schemas/Pydantic — 입출력의 모양 정의계산
dependencies.py주입할 것 — DB 세션·설정도메인 로직

6. 배포

  • 로컬: uvicorn ... --reload
  • 프로덕션: gunicorn + uvicorn worker 또는 컨테이너

⭐ 요약 한 문장 "실행의 주체를 스크립트에서 FastAPI 앱 + uvicorn으로 옮기고, 기존 클래스 메서드는 라우트가 호출하는 서비스로 둔다."

💡 Pydantic이란 데이터의 모양을 클래스로 선언해 두는 도구입니다. 선언해 두면 ① 들어오는 값이 그 모양인지 자동으로 검사하고 ② /docs 문서까지 자동으로 만들어 줍니다. /docs 는 Swagger UI 라고 부르는, 브라우저에서 API를 직접 눌러볼 수 있는 화면입니다.

4.6 requirements.txt 와 DI — 이름이 같아서 헷갈리는 둘

둘 다 '의존성(Dependency)'이라는 단어를 쓰지만 완전히 다릅니다. 이번 주에 반드시 갈라둬야 할 지점입니다.

requirements.txtDI (Dependency Injection · 의존성 주입)
무엇인가내 컴퓨터(가상환경)에 설치할 외부 패키지 목록객체가 사용할 다른 객체(도구)를 밖에서 던져주는 코딩 설계 기법
층환경의 문제설계의 문제
다루는 대상패키지 (pandas, fastapi …)객체 (DB 세션, 설정 …)
시점설치할 때 (실행 전)실행 중 (런타임)
비유마트에서 어떤 식재료를 사 올 것인가?요리사에게 어떤 칼을 쥐여줄 것인가?
코드·명령pip install -r requirements.txtDepends(get_db)
얻는 것어느 컴퓨터에서든 같은 환경결합도가 낮아져 부품 교체·테스트가 쉬워짐

DI의 장점을 한 줄로: 객체 간의 결합도를 낮춰 부품(클래스) 교체가 매우 쉬워지고, 테스트가 편리해집니다.

앞으로 다시 만납니다 3주차에서 DI는 DIP · IoC · 전략 패턴 · 포트&어댑터 와 함께 "쓰는 쪽은 인터페이스만 알고, 실제 물건은 밖에서 넣어준다" 라는 한 문장으로 통합됩니다.


5. 요청과 응답 — API의 기초

5.1 백엔드와 프론트엔드는 서로 다른 주소에 산다

이번 주에 실제로 두 개의 프로젝트를 갖게 됩니다.

example-com  (백엔드)     ← 데이터를 만들어 내보내는 쪽
example-md   (프론트엔드)  ← 화면을 그려 보여주는 쪽

          상호 간에 주고받는 방법 = API

왜 나눠 놓는가

이유설명
언어·런타임이 다름백엔드는 Python + uvicorn, 프론트는 TypeScript + Node.js
배포 주기가 다름화면 문구만 고칠 때 데이터 로직까지 다시 올릴 이유가 없음
책임이 다름화면이 바뀌어도 데이터 규칙은 그대로
보안사용자의 브라우저에 절대 노출되면 안 되는 것(키·DB 접속 정보)이 백엔드에만 있음

API (Application Programming Interface) — [프로그램끼리 대화하는 방법]인데, [서로의 내부를 모른 채, 미리 약속해 둔 창구로만 주고받는다]는 점에서 직접 호출과 구별된다.

비유: 식당의 주문 창구. 손님은 주방에 들어갈 수 없고, 창구를 통해서만 주문하고 받습니다. 창구의 규격만 지키면 주방을 통째로 바꿔도 손님은 아무것도 몰라도 됩니다.

5.2 API의 3요소와 CRUD

REST API 3요소 — 주소(무엇을?) + 방식(어떻게?) + 응답(결과는?)

CRUD — 데이터를 다루는 네 가지 기본 동작입니다.

CRUD뜻REST API 방식SQL
Create만들기POSTINSERT
Read보기GETSELECT
Update수정PUT / PATCHUPDATE
Delete삭제DELETEDELETE

CRUD는 무엇을 할지, REST API는 어떻게 요청할지, SQL은 DB에서 실제로 실행하는 방법입니다. 세 개가 같은 네 가지 동작을 각각의 언어로 말하고 있습니다.

이번 주에 만든 것을 3요소로 분해하면

요소이번 주의 실제 값
주소/titanic/data
방식GET
응답200 OK + 승객 정보 JSON

5.3 127.0.0.1 과 localhost 와 :8000

http://127.0.0.1:8000/titanic/data 라는 주소를 조각내 봅니다.

조각뜻
http://통신 규약(프로토콜)
127.0.0.1루프백 주소 — "이 컴퓨터 자신"
localhost127.0.0.1 의 별명 (둘은 같은 곳)
:8000포트 — 한 컴퓨터 안의 여러 문 중 8000번 문
/titanic/data경로(Path) — 그 서버 안에서 어떤 자원인지

비유: 127.0.0.1 은 건물 주소, 8000 은 호실 번호입니다. 한 건물(컴퓨터) 안에서 여러 프로그램이 각자 다른 호실(포트)을 씁니다. 그래서 포트가 겹치면 에러가 납니다.

⚠️ 127.0.0.1 은 내 컴퓨터에서만 열립니다. 옆자리 사람이 그 주소를 쳐도 자기 컴퓨터를 가리킬 뿐입니다. 진짜로 "누구나 요청할 수 있게" 하려면 배포가 필요합니다. 지금은 아직 절반만 온 상태입니다.

5.4 HTTP 상태코드 — 앞자리만 알아도 어디부터 볼지 정해진다

앞자리의미비유
2xx성공주문 완료
3xx이동다른 창구 안내
4xx요청 쪽 문제내 주문서를 확인
5xx서버 쪽 문제주방에서 문제 발생

자주 만나는 것

코드뜻
200 OK성공
201 Created새로 만들기 성공
204 No Content성공했지만 돌려줄 내용 없음
400 Bad Request요청 형식이 이상함
401 Unauthorized로그인 필요
403 Forbidden로그인은 했지만 권한 없음
404 Not Found주소·자료가 없음
405 Method Not AllowedGET 자리에 POST를 보냄
409 Conflict이미 가입된 이메일 등 충돌
422형식은 맞지만 내용 검증 실패
429 Too Many Requests요청 횟수 초과
500서버 내부 오류
502중간 서버 문제
503점검·과부하
504응답 지연

401 vs 403 — 401은 "너 누구야?", 403은 "누군지는 알지만 여기 못 들어와". 400 vs 422 — 400은 요청 모양 자체가 이상, 422는 모양은 맞는데 내용이 규칙 위반.

상태코드별 첫 확인 지점

코드어디부터 보나
400입력값 · 요청 형식 · 필수값
401 / 403로그인 · 토큰 · 권한 설정
404주소 · 라우팅 · API 경로
500서버 코드 · DB 연결 · 예외 로그

5.5 이 기능은 화면 쪽인가 서버 쪽인가

요청을 정확히 하기 위한 핵심 기준입니다. AI에게 시킬 때 특히 중요합니다.

클라이언트(화면)에 가까운 일서버가 필요한 일
버튼 색·배치 바꾸기로그인
메뉴 열고 닫기글·댓글 저장
다크모드 켜기내 정보 불러오기
입력 즉시 미리보기권한 확인

요청 문장 예시

  • 화면만: "서버 저장 없이 화면에서만 작동하게 해줘."
  • 서버 필요: "입력한 내용을 저장하고 다시 불러올 수 있게 해줘."
  • 검색은 범위를 말해야: "화면 목록만 검색할지, 저장된 전체 데이터에서 검색할지 구분해줘."

5.6 사용자는 DB와 직접 연결되지 않는다

사용자 → 서버 → DB       ⭕
사용자 → DB              ❌

은행 고객이 금고에 직접 들어갈 수 없는 것과 같습니다.

중간에 서버를 두는 네 가지 이유

  1. 권한 확인 — 이 사람이 이걸 볼 자격이 있는가
  2. 잘못된 요청 차단 — 형식·범위 검증
  3. 데이터 보호 — DB 접속 정보가 사용자에게 노출되지 않음
  4. 선행 처리 — 계산·가공·기록을 먼저 수행

⭐ 이번 주에 우리가 만든 것이 정확히 이 가운데 층입니다. CSV 파일(창고)을 사용자에게 직접 열어주는 대신, 서버가 읽어서 JSON으로 가공해 내보냅니다.