나혼자 코딩
Python 클래스와 객체 이해하기: OOP의 기초부터 실무 활용까지 본문
Python은 객체 지향 프로그래밍(Object-Oriented Programming, OOP)을 지원하는 언어로, 클래스(class)와 객체(object)의 개념을 바탕으로 코드를 보다 효율적이고 재사용 가능하게 작성할 수 있습니다. 본 글에서는 객체 지향 프로그래밍의 핵심 개념을 Python 문법을 중심으로 정리하고, 실무에서 클래스를 어떻게 활용할 수 있는지까지 함께 살펴보겠습니다.
1. 클래스와 객체란?
- 클래스(Class)는 데이터(속성)와 기능(메서드)을 하나로 묶는 사용자 정의 자료형의 설계도입니다.
- 객체(Object)는 클래스의 인스턴스로, 클래스를 기반으로 생성된 실체입니다.
예를 들어, "자동차"라는 클래스를 만든다면, 실제로 존재하는 "내 차, 친구 차"는 각각 하나의 객체입니다. 클래스는 공통된 구조를 정의하고, 객체는 그 구조를 바탕으로 동작하는 개별 실체입니다.
class Car:
def __init__(self, brand):
self.brand = brand
my_car = Car("Hyundai")
print(my_car.brand) # 출력: Hyundai
이처럼 클래스를 정의한 후 Car()
를 통해 인스턴스를 생성하면, 그 인스턴스는 해당 클래스의 모든 속성과 메서드를 사용할 수 있습니다.
2. 생성자 __init__()
클래스 인스턴스를 만들 때 자동으로 호출되는 특수 메서드가 __init__()
입니다. 이를 통해 객체의 초기 상태를 설정할 수 있습니다.
class User:
def __init__(self, name, age):
self.name = name
self.age = age
user1 = User("Alice", 30)
print(user1.name, user1.age)
self.name
,self.age
는 인스턴스 변수이며, 객체마다 고유한 값을 가집니다.- 생성자는 초기화 로직을 담기에 적절하며, 실무에서 객체 생성과 동시에 필수 데이터를 주입할 때 사용됩니다.
3. 인스턴스 변수와 메서드
- 인스턴스 변수는 객체마다 별도로 존재하는 속성입니다.
- 인스턴스 메서드는 클래스 내부에 정의된 함수로, 객체의 상태를 조회하거나 변경하는 데 사용됩니다.
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def discount(self, rate):
return self.price * (1 - rate)
item = Product("Laptop", 1000)
print(item.discount(0.1)) # 출력: 900.0
메서드는 항상 self
를 첫 번째 인자로 받으며, 이를 통해 인스턴스 변수에 접근하거나 수정할 수 있습니다. 이는 메서드가 특정 객체에 소속되어 있다는 것을 의미합니다.
4. self의 의미
self
는 인스턴스 메서드 내에서 현재 객체 자신을 참조하는 예약어입니다.- 모든 인스턴스 메서드는
self
를 통해 객체 내부 상태에 접근합니다.
class Demo:
def show(self):
print("Hello from", self)
obj = Demo()
obj.show() # self는 obj를 참조
실무에서 self
는 객체 간 데이터 공유, 내부 속성 조작, 메서드 간 호출 등에서 필수적인 역할을 합니다.
Tip: 클래스 밖에서 함수처럼 정의한 메서드에서 self를 빼먹는 실수를 종종 하게 되는데, 이는 TypeError를 발생시킵니다.
5. 클래스 변수 vs 인스턴스 변수
Python 클래스에서는 클래스 단위로 공유되는 변수와 인스턴스 단위로 독립적인 변수를 구분할 수 있습니다.
구분 | 정의 위치 | 접근 방식 | 공유 여부 |
클래스 변수 | 클래스 내부, 메서드 외부 | 클래스명 또는 인스턴스명 | 모든 인스턴스가 공유 |
인스턴스 변수 | 생성자(__init__) 또는 메서드 내 | self.변수명 | 각 인스턴스마다 개별 존재 |
class Counter:
count = 0 # 클래스 변수
def __init__(self):
Counter.count += 1
print(Counter.count) # 출력: 0
c1 = Counter()
c2 = Counter()
print(Counter.count) # 출력: 2
- 클래스 변수는 인스턴스 생성 횟수 카운팅, 공통 설정값 저장 등에 유용합니다.
- 반면, 인스턴스 변수는 각 객체의 고유한 속성을 저장할 때 사용합니다.
6. 상속과 오버라이딩
상속(Inheritance)은 기존 클래스의 기능을 물려받아 새로운 클래스를 정의하는 기법입니다. 이를 통해 코드의 중복을 줄이고 구조화된 설계를 가능하게 합니다.
- 부모 클래스: 공통 기능을 정의
- 자식 클래스: 부모 기능을 물려받고 필요에 따라 오버라이딩(재정의)
class Animal:
def speak(self):
print("소리를 냅니다.")
class Dog(Animal):
def speak(self): # 오버라이딩
print("멍멍!")
d = Dog()
d.speak() # 출력: 멍멍!
오버라이딩은 같은 이름의 메서드를 자식 클래스에서 새롭게 구현하여, 동일한 인터페이스로 다른 동작을 수행할 수 있도록 해줍니다. 이를 통해 다형성을 구현할 수 있습니다.
마무리
이번 글에서는 Python의 객체 지향 프로그래밍(OOP)의 기초를 다뤘습니다.
- 클래스는 데이터와 기능을 하나로 묶는 구조이며,
- 객체는 그 구조를 실체화한 개별 인스턴스입니다.
__init__()
생성자를 통해 객체 초기화를 수행하고,self
를 통해 객체 내부의 속성과 동작을 연결할 수 있습니다.- 클래스 변수와 인스턴스 변수의 차이를 이해하면 설계 유연성이 향상됩니다.
- 상속과 오버라이딩은 OOP의 핵심 원칙인 재사용성과 확장성을 실현하는 도구입니다.
이제 클래스와 객체의 기본 개념을 이해하셨다면, 다음 단계로는 추상 클래스, 다형성, 캡슐화, Mixin 패턴 등 고급 OOP 설계 패턴을 살펴보는 것이 좋습니다. 실무에 바로 적용 가능한 객체 지향 설계 감각을 키워봅시다!
'Python' 카테고리의 다른 글
Python 파일 입출력 완전 정복: open(), read(), write() (0) | 2025.04.12 |
---|---|
Python의 예외 처리: try, except, finally 그리고 예외 정의하기 (0) | 2025.03.17 |
Python의 주요 데이터 구조: 리스트, 튜플, 딕셔너리, 집합 (0) | 2025.03.12 |
Python 함수: 정의, 호출, 매개변수, 반환값 (0) | 2025.03.11 |
Python 제어문: 조건문과 반복문 (0) | 2025.03.08 |