목차
- 오늘 강의 개요
- 문자열(String) 활용 - strip, f-string
- 리스트(List) 기초 - 인덱스, append, for, enumerate
- 조건문 (if / if in) - 키워드 필터링
- 딕셔너리(Dictionary) 기초 - OpenAI 메시지 형식과 연결
- 함수(Function) - 정의, 파라미터, return
- 예외 처리 (try / except)
- 파일 입출력
- OpenAI 메시지 구조와 파이썬 자료구조 연결
- 핵심 개념 총정리
- 자주 나오는 실수 / 주의사항
1. 오늘 강의 개요
오늘은 OpenAI API를 다루기 위한 파이썬 기초 문법을 실습한다. 파이썬 문법 자체가 목표가 아니라, OpenAI API를 쓰기 위한 도구로서 배우는 것.
왜 이 파이썬 문법들을 배우나?
1
2
3
4
5
| 문자열(str) → 프롬프트(prompt) 조작, f-string으로 동적 프롬프트 생성
리스트(list) → messages 배열, 여러 질문 처리
딕셔너리(dict) → {"role": "user", "content": "..."} OpenAI 메시지 형식 그 자체!
함수(def) → API 호출 반복 코드를 재사용 가능하게 묶기
예외 처리 → API 오류, 없는 키 접근 등 안전하게 처리
|
2. 문자열(String) 활용 - strip, f-string
기본 문자열 조작
1
2
3
4
5
| response = "1단계 : 설정 열기, 2단계 : 비밀번호 변경, 3단계 : 저장하기"
len(response) # 38 (문자 수)
response.split(", ") # ['1단계 : 설정 열기', '2단계 : 비밀번호 변경', '3단계 : 저장하기']
len(response.split(", ")) # 3
|
.strip() - 앞뒤 공백 제거
1
2
| question = " 비밀번호를 잃어버렸어요 "
question.strip() # "비밀번호를 잃어버렸어요" ← 공백 제거됨
|
- ▶ 사용자 입력에는 항상 앞뒤 공백이 붙을 수 있어서 .strip() 필수!
f-string - 동적 프롬프트 생성 (매우 중요!)
1
2
3
4
5
6
7
8
9
10
11
12
13
| category = "계정"
question = " 비밀번호를 잃어버렸어요 "
prompt = f"""
카테고리 : {category}
질문 : {question.strip()}
답변형식 : 단계별로 설명해주세요
"""
print(prompt)
# 카테고리 : 계정
# 질문 : 비밀번호를 잃어버렸어요
# 답변형식 : 단계별로 설명해주세요
|
- ▶ f””” “”” : 여러 줄 f-string (삼중 따옴표)
- ▶ {변수명} : 변수 값을 문자열 안에 삽입
- ▶ {question.strip()} : 변수에 메서드 적용도 가능
LLM 프롬프트 작성 실전 패턴
1
2
3
4
5
| # 변수를 동적으로 바꿔가며 여러 질문을 만드는 패턴
categories = ["계정", "결제", "기술지원"]
for cat in categories:
prompt = f"당신은 {cat} 전문 상담원입니다. 질문: {question}"
# API 호출...
|
3. 리스트(List) 기초 - 인덱스, append, for, enumerate
리스트 생성 및 기본 조작
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| models = ['gpt-4o', 'gpt-4o-mini', 'claude-3']
scores = [0.95, 0.87, 0.72]
# 정방향 인덱스
models[0] # 'gpt-4o' (첫 번째)
models[2] # 'claude-3' (세 번째)
# 역방향 인덱스 ★ 유용!
models[-1] # 'claude-3' (마지막)
models[-2] # 'gpt-4o-mini' (뒤에서 두 번째)
# 요소 추가
models.append('gemini-2.5-flash')
len(models) # 4
|
- ▶ 음수 인덱스: -1은 항상 마지막, -2는 뒤에서 두 번째
- ▶ 이 패턴은 LLM 대화에서 “가장 최근 응답”을 꺼낼 때 자주 사용
for 루프 기본 순회
1
2
3
4
5
6
| for abc in models:
print(abc)
# gpt-4o
# gpt-4o-mini
# claude-3
# gemini-2.5-flash
|
enumerate - 인덱스 포함 순회 (★ 자주 쓰임)
1
2
3
4
5
6
| for i, abc in enumerate(models):
print(i, abc)
# 0 gpt-4o
# 1 gpt-4o-mini
# 2 claude-3
# 3 gemini-2.5-flash
|
- ▶ enumerate(리스트) → (인덱스, 값) 쌍으로 반환
- ▶ 번호를 붙여서 출력하거나, 인덱스 기반으로 다른 리스트와 매핑할 때 유용
4. 조건문 (if / if in) - 키워드 필터링
기본 if / else
1
2
3
4
5
6
7
8
9
10
| a = ['abcde', 'abc', 'bcd', 'efg']
for item in a:
if 'bc' in item:
print(item) # 'bc'가 포함된 것만 출력
else:
print(3)
# abcde
# abc
# bcd
# 3 ← 'efg'는 'bc' 없음
|
실습: IT 질문에서 키워드 필터링
1
2
3
4
5
6
7
8
9
10
11
12
13
| questions = [
'비밀번호를 잊어버렸어요.',
'계정이 해킹당했어요.',
'로그인이 안 돼요.',
'이메일을 변경하고 싶어요.',
'2단계 인증이 안 돼요.'
]
keyword = "비밀번호"
for i, q in enumerate(questions):
if keyword in q:
print(f"{i}, {q}")
# 0, 비밀번호를 잊어버렸어요.
|
- ▶
keyword in item : item 문자열 안에 keyword가 포함되면 True - ▶ 이 패턴 = 간단한 키워드 기반 문서 검색의 기본
5. 딕셔너리(Dictionary) 기초 - OpenAI 메시지 형식과 연결
딕셔너리 기본 구조
1
2
3
4
5
6
| person = {'name': '홍길동', 'age': 30}
person['name'] # '홍길동'
person['age'] # 30
# 새 키 추가
person['email'] = 'hong@test.com'
|
★ OpenAI 메시지 = 딕셔너리!
1
2
3
4
5
6
7
8
9
10
11
12
13
| # OpenAI API의 메시지 형식
message = {
'role' : 'user',
'content': '비밀번호를 잃어버렸다'
}
message['role'] # 'user'
message['content'] # '비밀번호를 잃어버렸다'
# timestamp 같은 정보 추가도 가능
message['timestamp'] = '2026-03-11'
message
# {'role': 'user', 'content': '비밀번호를 잃어버렸다', 'timestamp': '2026-03-11'}
|
- ▶ 즉, OpenAI API에 넘기는 messages 리스트는 “딕셔너리의 리스트”
대화 히스토리 = 딕셔너리 리스트
1
2
3
4
5
6
7
8
9
10
11
| messages = [
{"role": "system", "content": "당신은 IT 상담원입니다"},
{"role": "user", "content": "비밀번호를 잊어버렸어요"},
{"role": "assistant", "content": "비밀번호 재설정 방법을 안내드리겠습니다"}
]
for msg in messages:
print(f"[{msg['role']}] {msg['content']}")
# [system] 당신은 IT 상담원입니다
# [user] 비밀번호를 잊어버렸어요
# [assistant] 비밀번호 재설정 방법을 안내드리겠습니다
|
.get() 메서드 - KeyError 방지 (중요!)
1
2
3
4
5
6
7
8
9
10
11
12
13
| config = {'model': 'gpt-4o-mini', 'temperature': 0.7, 'max_tokens': 1000}
# dict[key] 방식 - 키 없으면 KeyError 발생!
config['없는키'] # KeyError!
# .get(key) 방식 - 키 없으면 None 반환
config.get('model') # 'gpt-4o-mini'
config.get('max_tokens') # 1000
config.get('없는키') # None (에러 없음)
# .get(key, 기본값) - 키 없으면 기본값 반환
config.get('없는키', 100) # 100 (기본값)
config.get('max_tokens', 100) # 1000 (키 있으면 실제 값)
|
- ▶ .get() 을 쓰는 것이 안전한 딕셔너리 접근 방법
- ▶ 특히 API 응답처럼 예상치 못한 키가 없을 수 있는 경우에 필수
6. 함수(Function) - 정의, 파라미터, return
기본 함수 정의
1
2
3
4
5
6
7
8
9
10
11
12
13
| def 인사(name):
print(f"안녕하세요, {name} 님!")
인사('이상호') # 안녕하세요, 이상호 님!
인사('이상호2') # 안녕하세요, 이상호2 님!
# num 파라미터 추가 + return
def 인사(name, num):
print(f"안녕하세요, {name} 님!" * num) # num번 반복 출력
return f"안녕하세요, {name} 님!" # 호출한 곳에 값 반환
result = 인사('이상호', 3)
# 안녕하세요, 이상호 님!안녕하세요, 이상호 님!안녕하세요, 이상호 님!
|
기본값(default) 파라미터
1
2
3
4
5
6
7
8
9
| def make_prompt(question, language='한국어'):
prompt = f"다음 질문에 {language}로 답변해주세요 : {question}"
return prompt
make_prompt("비밀번호 재설정 방법")
# '다음 질문에 한국어로 답변해주세요 : 비밀번호 재설정 방법'
make_prompt("비밀번호 재설정 방법", "영어")
# '다음 질문에 영어로 답변해주세요 : 비밀번호 재설정 방법'
|
- ▶ language=’한국어’ : 기본값 설정 → 인자 생략 시 기본값 사용
- ▶ 자주 쓰는 파라미터는 기본값을 설정해두면 편리
OpenAI 연동 유틸 함수
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| def make_message(role_value, content_value):
"""OpenAI 메시지 딕셔너리 생성"""
message = {'role': role_value, 'content': content_value}
return message
# 사용
msg = make_message("user", "비밀번호가 없습니다")
# {'role': 'user', 'content': '비밀번호가 없습니다'}
# 대화 구성에 활용
messages = [
make_message("system", "당신은 IT 상담원입니다"),
make_message("user", "비밀번호를 잊어버렸어요"),
make_message("assistant", "비밀번호 재설정 안내드립니다"),
]
|
- ▶ 반복되는 딕셔너리 생성을 함수로 묶으면 코드가 간결해짐
- ▶ 실무에서 자주 쓰는 패턴
7. 예외 처리 (try / except)
기본 try / except
1
2
3
4
| try:
result = 10 / 0 # ZeroDivisionError 발생!
except:
print("에러 발생") # 에러 시 이 코드 실행
|
config에서 없는 키 안전하게 접근
1
2
3
4
5
6
7
8
9
10
| config = {'model': 'gpt-4o-mini'}
# .get() 방법
temperature = config.get('temperature', 0.5) # 없으면 0.5
# try/except 방법
try:
temperature = config['temperature']
except KeyError:
temperature = 0.5 # 기본값
|
- ▶ .get(key, default) 와 try/except 두 가지 방법 모두 가능
- ▶ 단순한 경우는 .get() 이 간결하고, 복잡한 로직은 try/except 사용
8. 파일 입출력
텍스트 파일 쓰기 / 읽기
1
2
3
4
5
6
7
8
| # 쓰기 (w 모드)
with open('data.txt', 'w', encoding='utf-8') as f:
f.write("안녕하세요")
# 읽기 (r 모드)
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
print(content) # "안녕하세요"
|
- ▶ with open() 으로 파일 열기 → with 블록 끝나면 자동으로 파일 닫힘
- ▶ encoding=’utf-8’ 한글 처리 시 필수
JSON 파일 저장/로드
1
2
3
4
5
6
7
8
9
10
11
| import json
data = {"model": "gpt-4o-mini", "messages": [...]}
# 저장
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 로드
with open('data.json', 'r', encoding='utf-8') as f:
loaded = json.load(f)
|
- ▶ ensure_ascii=False : 한글이 \uXXXX 로 변환되지 않고 그대로 저장
- ▶ indent=2 : 들여쓰기 2칸으로 보기 좋게 저장
디렉토리 생성
1
2
3
| import os
os.makedirs('sample_output', exist_ok=True)
# exist_ok=True : 폴더가 이미 있어도 에러 없이 넘어감
|
9. OpenAI 메시지 구조와 파이썬 자료구조 연결
오늘 배운 파이썬 → OpenAI API 어디에 쓰이나?
| 파이썬 자료구조 | OpenAI API에서 사용 |
|---|
| 딕셔너리 (dict) | 메시지 하나 {“role”: “user”, “content”: “…”} |
| 리스트 (list) | messages 배열 [{…}, {…}, {…}] |
| f-string | 프롬프트 동적 생성 f”당신은 {role} 전문가입니다” |
| 함수 (def) | API 호출 재사용 함수 def ask_gpt(question): … |
| for 루프 | 여러 질문 반복 처리 |
| .get() | response에서 안전하게 값 꺼내기 |
실전 통합 예시
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| from openai import OpenAI
client = OpenAI()
def ask_gpt(role, question):
"""역할 기반 LLM 호출 함수"""
messages = [
{"role": "system", "content": f"당신은 {role}입니다."},
{"role": "user", "content": question}
]
response = client.chat.completions.create(
model = "gpt-4o-mini",
messages = messages
)
return response.choices[0].message.content
# 여러 역할로 같은 질문 물어보기
roles = ["수학 선생님", "수의사", "요리사"]
question = "1+1은?"
for role in roles:
answer = ask_gpt(role, question)
print(f"[{role}]: {answer[:50]}")
|
10. 핵심 개념 총정리
| 개념 | 핵심 내용 |
|---|
| f-string | 동적 프롬프트 생성: f”당신은 {role}입니다” |
| .strip() | 앞뒤 공백 제거 (사용자 입력 정제) |
| enumerate() | 인덱스 포함 순회 (번호 출력 등에 활용) |
| keyword in item | 문자열 포함 여부 확인 (키워드 필터링) |
| 딕셔너리 | OpenAI 메시지 형식 그 자체 |
| .get(key, default) | KeyError 방지 안전한 딕셔너리 접근 |
| 함수 def | 반복 코드를 묶어 재사용 가능하게 |
| try/except | 에러 상황 안전하게 처리 |
| with open() | 파일 안전하게 열기 (자동 닫힘) |
| json.dump/load | 딕셔너리를 파일로 저장하고 불러오기 |
11. 자주 나오는 실수 / 주의사항
실수 1: 리스트 인덱스 범위 초과
1
2
3
| models = ['gpt-4o', 'gpt-4o-mini', 'claude-3']
models[5] # IndexError! (인덱스 0~2 만 유효)
models[-1] # ← 마지막 요소는 이렇게
|
실수 2: 딕셔너리에서 없는 키 직접 접근
1
2
3
| config = {'model': 'gpt-4o-mini'}
config['temperature'] # KeyError!
config.get('temperature', 0.7) # 0.7 (기본값 반환)
|
실수 3: f-string 중괄호 빠뜨리기
1
2
3
| name = "홍길동"
print(f"안녕하세요, name 님!") # 변수가 들어가지 않음!
print(f"안녕하세요, {name} 님!") # 올바른 코드
|
실수 4: 파일 인코딩 미지정
1
2
3
4
5
6
| # 한글 파일 읽을 때 인코딩 빠뜨리면 UnicodeDecodeError!
with open('data.txt', 'r') as f: # 위험
content = f.read()
with open('data.txt', 'r', encoding='utf-8') as f: # 안전
content = f.read()
|
끝