Application/Python

[Python] 파이썬 클래스, 객체지향이란 무엇일까

devsalix 2026. 5. 8. 08:58
728x90

파이썬 클래스, 객체지향이란 무엇일까

지난번에 계산기 미니 프로젝트 만들면서 살짝 답답한 부분 못 느끼셨어요? 더하기, 빼기, 곱하기, 나누기 함수 네 개가 그냥 따로따로 떠다니고 있었거든요. 분명 다 "계산기"라는 한 덩어리에 속하는 기능들인데, 코드만 보면 별 상관없는 함수들이 줄지어 서 있는 모양새였죠.

오늘 그 답답함을 풀 차례예요. 이게 바로 클래스라는 친구의 등장 신호고, 흔히 말하는 객체지향이라는 사고방식의 시작점이기도 합니다. 드디어 중급 영역으로 넘어왔어요.


객체지향이란 게 도대체 뭔가요

이름이 거창해서 그렇지, 핵심은 한 줄이에요.

관련 있는 데이터랑 기능을 한 덩어리로 묶어서 다루는 방식.

이게 끝입니다. 진짜로요. 책에 보면 캡슐화니 다형성이니 어려운 단어들이 줄줄이 나오는데, 처음엔 그거 다 무시하셔도 돼요. 일단 "흩어진 거 묶는다" 이 감만 잡으시면 충분하거든요.


클래스는 설계도, 인스턴스는 실제 물건

비유 하나 들어갈게요. 붕어빵 틀 본 적 있으시죠.

붕어빵 틀이 클래스예요. 모양이랑 구조가 정의되어 있는 거죠. 그리고 그 틀에 반죽 부어서 실제로 구워낸 붕어빵이 인스턴스고요. 틀 하나로 빵 100개를 찍어낼 수 있고, 어떤 빵에는 팥을 넣고 어떤 빵에는 슈크림을 넣을 수도 있어요. 같은 틀에서 나왔지만 내용물은 각자 다른 거예요.

여기서 꼭 기억하실 게 하나 있어요.

틀만 만들어두면 빵이 저절로 안 나옵니다. 반죽을 부어서 찍어내야 빵이 생기죠.

코드도 똑같아요. 클래스 정의만 해놓는다고 아무 일도 안 일어나요. 그 클래스로 인스턴스를 만들어야 비로소 뭔가 시작됩니다.


파이썬 클래스 기본 문법 살펴보기

가장 단순한 클래스부터 가볼게요.

# 클래스 정의: 일단 내용물은 비워두기
class Dog:
    pass  # 비어있다는 표시. 나중에 채울 거예요

# 인스턴스 만들기: 클래스 이름 뒤에 괄호
my_dog = Dog()

# 만들어진 인스턴스 출력해보기
print(my_dog)

 

실행하면 이런 게 나와요.

<__main__.Dog object at 0x000001E3A5F8>

 

뭐 이상한 주소처럼 생긴 게 떴는데, "Dog 클래스로 만들어진 객체 하나가 메모리 어딘가에 자리 잡았다"는 뜻이에요. 일단은 그냥 "아, 만들어졌구나" 정도로 넘기시면 됩니다.

참고로 클래스 이름은 첫 글자를 대문자로 쓰는 게 관례예요. Dog, Calculator, UserAccount 이런 식으로요. 안 지켜도 동작은 하는데, 다른 사람이 코드 봤을 때 "아 이건 클래스구나" 하고 바로 알아보거든요.


메서드 추가하기

빈 깡통 클래스는 재미없으니까 기능을 하나 넣어볼게요.

class Dog:
    # 클래스 안에 들어간 함수를 메서드라고 불러요
    def bark(self):
        print("멍멍!")

my_dog = Dog()  # 강아지 한 마리 만들기
my_dog.bark()   # 점 찍고 메서드 부르기

 

멍멍!

 

함수처럼 생겼는데 클래스 안에 들어가면 이름이 바뀝니다. 메서드라고 불러요. 본질은 함수랑 똑같아요. 어디 소속됐냐의 차이일 뿐이에요.

호출할 때는 my_dog.bark()처럼 점을 찍어서 부릅니다. "이 강아지야, 짖어봐"라고 시키는 느낌이잖아요.


self는 왜 항상 따라다닐까

근데 메서드 정의할 때 self라는 게 첫 자리에 있죠. 이게 처음엔 진짜 헷갈리실 거예요. 저도 그랬거든요.

일단 가볍게는 이렇게 외우시면 돼요.

"메서드 정의할 땐 첫 자리에 무조건 self를 적는다."

 

그게 약속이에요. 정확히 뭐냐면, self이 메서드를 부른 그 인스턴스 자기 자신을 가리킵니다.

my_dog.bark()라고 부르면 파이썬이 속으로 "아 my_dog이 짖으라고 했구나" 하면서 my_dog을 첫 인자로 슬쩍 넣어줘요. 그래서 받을 자리가 메서드 안에 있어야 하고, 그 자리가 바로 self인 거죠.

자기가 누군지 알아야 자기 데이터를 다룰 수 있잖아요. 그 통로 역할이라고 보시면 됩니다.


같은 클래스, 다른 인스턴스

self의 진가는 정보를 담을 때 드러나요.

class Dog:
    def set_name(self, name):
        # 자기 자신에게 name이라는 이름표 붙이기
        self.name = name

    def bark(self):
        # 자기 이름이랑 같이 짖기
        print(f"{self.name}: 멍멍!")

dog1 = Dog()            # 첫 번째 강아지
dog1.set_name("초코")   # 이름은 초코

dog2 = Dog()            # 두 번째 강아지
dog2.set_name("바둑이")  # 이름은 바둑이

dog1.bark()
dog2.bark()

 

초코: 멍멍!
바둑이: 멍멍!

 

같은 Dog 클래스에서 만든 인스턴스인데 각자 자기만의 name을 가지고 있어요. 붕어빵 틀은 하나지만 안에 든 내용물은 다른 거랑 똑같죠.

self.name = name이 핵심이에요. "이 인스턴스 안에 name이라는 자기만의 변수를 박아둔다"는 뜻이거든요.


python class로 계산기 다시 묶어보기

자, 이제 지난번 계산기로 돌아갈 시간이에요.

class Calculator:
    def add(self, a, b):
        return a + b  # 더하기

    def subtract(self, a, b):
        return a - b  # 빼기

    def multiply(self, a, b):
        return a * b  # 곱하기

    def divide(self, a, b):
        if b == 0:
            return "0으로 나눌 수 없어요"  # 예외 처리
        return a / b

calc = Calculator()        # 계산기 한 대 만들기
print(calc.add(3, 5))      # 8
print(calc.divide(10, 0))  # 0으로 나눌 수 없어요

 

지난번엔 함수 4개가 따로 흩어져 있었는데, 이제는 Calculator라는 한 덩어리예요. "계산기 한 대"라는 단위로 다룰 수 있게 된 거죠. 보기에도 훨씬 깔끔하잖아요.


처음에 자주 하는 실수

self 빠뜨리기. 메서드 만들 때 def bark(): 이렇게 self를 안 적으면 호출하는 순간 이런 에러가 나요.

TypeError: bark() takes 0 positional arguments but 1 was given

 

"0개 받기로 했는데 1개 줬다"고 나오는데, 거의 다 self 빠뜨린 경우예요.

괄호 빠뜨리기. Dog()이 아니라 그냥 Dog이라고 쓰면 인스턴스가 안 만들어져요. 설계도한테 짖으라고 하는 꼴이거든요. 반드시 괄호 붙여서 실제 강아지를 만들어주세요.


다음 글 예고

오늘은 클래스의 모양만 익혔어요. 그런데 강아지마다 이름 붙이려고 매번 set_name을 따로 부르는 거, 좀 번거롭다고 느끼셨죠.

다음에는 인스턴스를 만들 때 한 방에 정보를 같이 넘기는 방법을 다룰 거예요. __init__이라는 좀 특이한 이름의 메서드인데, 이거 익히고 나면 클래스가 진짜 쓸 만해집니다.


 


제 글이 도움이 되셨다면 댓글 & 공감 부탁드려요 😀

 

 
728x90