Python 시작하기 #5 : 객체, 클래스, 인스턴스
안녕하세요:) 이번 포스팅에서는 Python의 객체(Object), 클래스(Class), 인스턴스(Instance) 개념을 국립공원 실시간 탐방로 통제정보 예시로 알아보겠습니다.
실습링크
https://github.com/jjangmo91/ParkLab/blob/main/Python/06_Object_Class_Instance.ipynb
ParkLab/Python/06_Object_Class_Instance.ipynb at main · jjangmo91/ParkLab
Contribute to jjangmo91/ParkLab development by creating an account on GitHub.
github.com
객체(Object)
파이썬에서는 현실의 다양한 대상을 객체로 다룹니다. 객체(Object)란 여러 정보를 담은 "상태(데이터, 속성)"와 그 정보를 바탕으로 할 수 있는 "동작(함수, 메서드)"을 하나로 묶은 프로그래밍 세계의 실체입니다.
예시를 통해 한눈에 살펴보겠습니다. 국립공원 홈페이지에 접속하면 각 국립공원별로 실시간 탐방통제정보를 제공하고 있습니다. 각 국립공원마다 여러 탐방로가 있고, 각 탐방로마다 개방, 부분통제, 전면통제 등 상태와 통제 사유(기상, 산불, 공사 등)가 실시간으로 제공됩니다.
- 국립공원은 이름, 위치, 여러 탐방로 목록 등 정보(속성)를 갖고
- 탐방로는 이름, 현재 상태(개방/부분통제/전면통제), 통제 사유 등 다양한 속성을 갖습니다.
- 통제/개방 여부 판별, 사유 안내, 현황 전체 출력 등 다양한 행동(메서드)도 수행할 수 있습니다.
이렇게 다양한 상태와 행동이 결합된 실체가 바로 파이썬의 "객체"입니다.



클래스(Class)와 인스턴스(Instance)
클래스는 객체를 만들기 위한 "설계도" 입니다. 탐방로라는 클래스를 한 번 정의해 두면 이름, 상태(개방/부분통제/전면통제), 통제 사유, 개방 여부 판별 등 모든 탐방로에 공통적으로 적용할 정보(속성)와 기능(메서드)을 한 번에 관리할 수 있습니다.
인스턴스는 이 설계도(클래스)로부터 실제로 만들어진 "구체적인 객체"입니다. 예를 들어, "문장대" 탐방로, "천왕봉" 탐방로 각각은 Trail 클래스의 인스턴스(=객체)가 됩니다.
국립공원 역시 마찬가지로, "속리산국립공원", "설악산국립공원" 등 각각이 NationalPark 클래스의 인스턴스로 만들어집니다.
중요 포인트
클래스는 국립공원, 탐방로처럼 종류별로 한 번만 정의하고, 실제 데이터(속리산, 설악산, 문장대, 천왕봉 등)는 인스턴스(객체)로 여러 개 생성해 계층적으로 관리합니다. 이렇게 객체지향적 구조로 만들면, 국립공원과 탐방로처럼 계층적이면서도 복잡한 상태(개방/부분통제/전면통제)와 실시간 변화를 실제와 비슷하게 효과적으로 관리하고, 다양한 분석 · 확장도 훨씬 쉽게 할 수 있습니다.
국립공원/탐방로 클래스(설계도) 만들기
클래스 선언은 class NationalPark:처럼 시작합니다. __init__ 함수(생성자)는 객체가 생성될 때 자동으로 실행되며, 국립공원의 이름(name), 위치(location)를 입력받아 저장하고, 탐방로 객체를 담을 빈 리스트(self.trails)도 준비합니다. 여기서 self는 앞으로 만들어질 각 객체 자신을 가리키는 파이썬의 약속된 첫 번째 인자입니다.
add_trail 메서드는 새로운 탐방로 객체를 이 공원의 탐방로 리스트에 추가할 때 사용합니다.
get_park_status 메서드는 소속된 모든 탐방로의 상태를 종합해, 공원 전체의 개방/부분통제/전면통제 상태를 문자열로 반환합니다. 이때 all()함수를 이용하면 리스트 전체가 특정 조건을 만족하는지 빠르게 판별할 수 있습니다.
describe 메서드는 공원의 이름, 위치, 전체 상태, 탐방로 수를 한 줄로 요약한 문자열로 반환하며
show_trail_status 메서드는 공원 소속 모든 탐방로의 상태(이름, 통제 여부, 사유 등)를 사람이 보기 좋게 한 번에 출력합니다.
# NationalPark 클래스 정의
class NationalPark:
def __init__(self, name, location):
self.name = name
self.location = location
self.trails = [] # 탐방로 객체(인스턴스)를 담는 리스트
def add_trail(self, trail):
"""탐방로(객체)를 동적으로 추가하는 메서드"""
self.trails.append(trail)
def get_park_status(self):
"""
전체 탐방로의 상태로 공원 상태를 반환
- 모든 탐방로가 '개방'이면 '개방'
- 모든 탐방로가 '전면통제'이면 '전면통제'
- 그 외 하나라도 통제면 '부분통제'
"""
if not self.trails:
return "정보없음"
if all(t.status == "개방" for t in self.trails):
return "개방"
elif all(t.status == "전면통제" for t in self.trails):
return "전면통제"
else:
return "부분통제"
def describe(self):
status = self.get_park_status()
return f"{self.name} ({self.location}) - 전체 상태: {status}, 탐방로 수: {len(self.trails)}"
def show_trail_status(self):
print(f"[{self.name} 탐방로 현황]")
for t in self.trails:
print(" -", t.info())
객체지향 프로그래밍에서는 각 객체(인스턴스)마다 고유한 정보를 저장할 수 있어야 합니다. 이때 사용하는 것이 바로 인스턴스 변수(instance varibale)입니다. 아래 Trail 클래스는 국립공원의 한 탐방로 정보를 표현합니다. 클래스를 기반으로 여러 탐방로 객체를 만들 때, 각각의 이름(name), 상태(status), 통제 사유(reason)는 모두 독립적으로 관리되며, 이 정보들이 바로 인스턴스 변수로 저장됩니다.
여기서 self로 시작하는 변수가 바로 인스턴스 변수입니다. 이 변수들은 객체마다 따로 존재하기 때문에, 여러 개의 Trail 객체를 만들어도 서로의 정보에 영향을 주지 않습니다.
# Trail 클래스를 정의
class Trail:
def __init__(self, name, status, reason=None):
self.name = name
self.status = status
self.reason = reason
def info(self):
if self.status == "개방":
return f"{self.name}: 개방"
elif self.status == "부분통제":
return f"{self.name}: 부분통제 ({self.reason})"
else:
return f"{self.name}: 전면통제 ({self.reason})"
인스턴스(객체) 생성 및 동적 탐방로 추가
여기서는 먼저 국립공원 객체(인스턴스)를 생성하고, 탐방로 정보는 처음에 비워둡니다. 이렇게 하면 상황에 따라 동적으로 탐방로 정보를 하나씩 추가할 수 있습니다. 예를 들어, 속리산국립공원, 설악산국립공원 객체만 먼저 만든 뒤 실제 데이터(탐방로 이름, 통제 여부, 사유 등)에 따라 .add_trail() 메서드를 활용해 탐방로 정보를 나중에 자유롭게 추가할 수 있습니다.
# 국립공원 객체(인스턴스) 먼저 생성(탐방로 비워둠)
songnisan = NationalPark("속리산국립공원", "충북 보은")
seoraksan = NationalPark("설악산국립공원", "강원 속초")
parks = [songnisan, seoraksan]
# 나중에 데이터에 따라 탐방로를 동적으로 추가 (수동, 자동, 반복문 등 가능)
songnisan.add_trail(Trail("문장대", "전면통제", "기상악화"))
songnisan.add_trail(Trail("천왕봉", "개방"))
songnisan.add_trail(Trail("법주사", "부분통제", "공사"))
songnisan.add_trail(Trail("비로봉", "개방"))
seoraksan.add_trail(Trail("대청봉", "전면통제", "산불위험"))
seoraksan.add_trail(Trail("울산바위", "전면통제", "산불위험"))
seoraksan.add_trail(Trail("공룡능선", "전면통제", "산불위험"))
seoraksan.add_trail(Trail("비선대", "전면통제", "산불위험"))
활용 예시
이처럼 객체지향 방식으로 국립공원 객체를 먼저 만들어두고 실제 데이터(탐방로 현황)에 따라 탐방로 객체를 동적으로 추가하면 다양한 상황 변화, 대규모 데이터에도 손쉽게 대응할 수 있습니다.
실전 환경에서는 반복문, 파일 입력, 사용자 입력 등과 연계해 효율적으로 탐방로 정보를 관리할 수 있는 확장성 높은 구조를 구현할 수 있습니다.
# 공원별 전체 상태 요약(대시보드)
for park in parks:
print(f"{park.name} {park.get_park_status()}")
# 특정 공원 선택시 상세 탐방로 현황
print("\n[속리산국립공원 상세 탐방로 현황]")
songnisan.show_trail_status()