오늘은 단순히 파이썬 문법을 배우는 수준을 넘어, 실제 개발 프로젝트에서 사용하는 구조를 이해하는 데 초점을 맞춘 하루였다. 오전에는 예외 처리와 JSON 파일을 다루는 방법을 익혔고, 오후에는 프로젝트 구조를 설계하는 방법과 Git을 이용한 협업까지 경험했다. 특히 코드 한 줄을 작성하는 것보다 "왜 이렇게 구조를 나누는지"를 계속 생각하게 된 하루였다.
예외 처리가 왜 필요한지 이해하다
오늘 가장 먼저 배운 내용은 예외 처리(Exception Handling)였다.
그동안은 프로그램에서 오류가 발생하면 그대로 종료되는 것이 당연하다고 생각했는데, 실제 프로그램은 오류가 발생해도 사용자에게 적절한 안내를 하고 계속 동작해야 한다는 것을 배웠다.
예를 들어 존재하지 않는 파일을 읽는 상황에서는 FileNotFoundError가 발생한다.
이때 try-except를 사용하면 프로그램이 종료되지 않고 원하는 메시지를 출력하거나 다른 동작을 수행할 수 있다.
try:
text = file_path.read_text(encoding="utf-8")
except FileNotFoundError:
print("파일을 찾을 수 없습니다.")
처음에는 단순히 문법 하나를 배우는 것 같았지만, 실제 서비스에서는 사용자가 어떤 입력을 할지 알 수 없기 때문에 예외 처리는 필수라는 점을 이해하게 되었다.
또 raise를 이용해 예외를 직접 발생시키고, 그 예외를 호출한 곳에서 처리하는 구조도 배웠다.
처음에는 조금 어려웠지만 "문제가 발생하면 호출한 곳에 알려준다." 정도로 이해하니 조금씩 감이 잡히기 시작했다.
JSON 파일을 읽고 Python Dictionary로 사용하는 방법
오늘은 JSON 파일도 처음으로 직접 다뤄봤다.
지금까지는 Dictionary만 사용했는데, 실제 프로젝트에서는 설정 파일이나 데이터가 대부분 JSON 형태로 저장되어 있다는 것도 알게 되었다.
JSON 파일을 읽을 때는
import json
data = json.loads(text)
처럼 Dictionary로 변환해서 사용한다.
그래서
data["app_name"]
처럼 기존 Dictionary와 동일하게 접근할 수 있었다.
또 JSON 문법이 잘못되었을 때 발생하는 JSONDecodeError도 함께 처리하면서 파일이 없을 때와 문법이 틀렸을 때를 각각 다르게 처리하는 방법도 배웠다.
SyntaxError와 예외는 다르다는 것을 알게 되었다
오늘 헷갈렸던 부분 중 하나가 SyntaxError였다.
처음에는 모든 오류를 예외 처리하면 되는 줄 알았는데,
SyntaxError는 코드 자체의 문법이 틀린 것이기 때문에 프로그램이 실행되기 전부터 발생하는 오류였다.
반면
- FileNotFoundError
- JSONDecodeError
같은 오류는 프로그램이 실행되는 중에 발생하기 때문에 try-except로 처리할 수 있다는 차이도 이해하게 되었다.
프로젝트 구조를 나누는 이유
오후부터는 프로젝트 구조를 만드는 방법을 배웠다.
지금까지는 하나의 파일 안에 모든 코드를 작성했지만, 실제 프로젝트에서는 역할별로 파일을 나누어 관리한다.
오늘 만든 구조는 대략 다음과 같았다.
project
│
├── main.py
├── app
│ ├── services.py
│ └── models.py
main.py는 사용자와 직접 만나는 화면(UI)의 역할을 하고,
service는 실제 데이터를 처리하는 역할을 담당한다.
강사님께서
"화면은 화면만 만들고, 기능은 서비스에서 만든다."
라고 설명하셨는데, 왜 파일을 나누는지 조금 이해가 되기 시작했다.
Dictionary 대신 dataclass(Model)를 사용하는 이유
오전에는 Dictionary를 이용해서 여러 데이터를 전달했는데,
오후에는 dataclass를 이용한 Model 클래스를 만들었다.
@dataclass
class ResponseChatMessage:
answer: str
model: str
message: str = "OK"
Dictionary도 데이터를 담을 수 있지만
- 자동완성이 가능하고
- 타입을 알 수 있으며
- 설명을 작성할 수 있고
- 유지보수가 쉬운
Model 클래스를 사용하는 것이 훨씬 실무적이라는 것을 배웠다.
앞으로 프로젝트를 만들 때도 이런 구조를 계속 사용하게 될 것 같다.
화면(Main)과 서비스(Service)를 분리하는 구조
오늘 가장 인상 깊었던 부분은 프로그램의 흐름이었다.
사용자
↓
Main(UI)
↓
Service
↓
LLM
↓
Response Model
↓
Main(UI)
화면은 사용자 입력만 받고,
실제 작업은 Service에서 처리한 뒤,
결과만 다시 화면으로 전달하는 구조였다.
또 Service에서 문제가 발생하면
raise ConnectionAbortedError(...)
처럼 예외를 발생시키고,
Main에서는
try:
...
except ConnectionAbortedError:
...
로 처리하는 방식도 실습했다.
처음에는 복잡해 보였지만 역할을 나누니 코드가 훨씬 보기 좋아지는 것을 느꼈다.
Git 브랜치를 이용한 협업을 처음 경험하다
마지막 시간은 Git 협업이었다.
오늘 가장 많이 시행착오를 겪은 부분이기도 하다.
오늘 진행한 순서는
- Repository 생성
- Collaborator 추가
- Clone
- Branch 생성
- Commit
- Push
였다.
특히
jso
origin/jso
의 차이를 이해하는 것이 가장 중요했다.
처음에는 Commit을 했는데 GitHub 사이트가 업데이트되지 않아 계속 헷갈렸는데,
알고 보니
Commit
↓
로컬 브랜치(jso)
↓
Push
↓
GitHub(origin/jso)
순서로 동작하는 것이었다.
또 Merge Conflict도 직접 경험했다.
처음에는
<<<<<<< HEAD
=======
>>>>>>>
같은 표시를 보고 당황했지만, 충돌이 난 부분을 직접 수정하고 git add, git rebase --continue를 실행하면서 Git이 어떻게 동작하는지 조금씩 이해할 수 있었다.
실제로 충돌을 겪어보니 Git을 책으로만 배우는 것보다 훨씬 기억에 오래 남을 것 같다.
오늘 느낀 점
오늘은 지금까지 수업 중 가장 실무적인 느낌이 강했던 하루였다.
예외 처리, JSON 파일, 프로젝트 구조, Model 클래스, Service 분리, Git 브랜치 협업까지 모두 실제 개발에서 사용하는 방식이라는 점이 인상적이었다.
특히 강사님께서 계속 강조하신
"흐름을 이해해야 한다."
라는 말이 가장 기억에 남는다.
아직은 코드 하나하나를 모두 이해하는 것은 어렵지만, 프로그램이 어떤 순서로 실행되고 어떤 역할을 하는지 조금씩 보이기 시작했다.
Git은 여전히 익숙하지 않지만, 직접 충돌을 해결해 보면서 Git이 어떻게 동작하는지도 많이 배울 수 있었다.
오늘 배운 내용을 잘 복습해서 앞으로 진행될 AI 프로젝트에서도 자연스럽게 활용할 수 있도록 연습해야겠다.
오늘 배운 핵심 키워드
- Exception Handling
- try-except
- raise
- FileNotFoundError
- JSONDecodeError
- SyntaxError
- JSON
- Dictionary
- dataclass
- Model
- Service
- Main(UI)
- 프로젝트 구조
- Git Branch
- Commit
- Push
- origin
- Merge Conflict
- Rebase
- GitHub 협업
댓글