Python 클래스(Class) 소개: 객체와 인스턴스 이해하기

Ad Placeholder

Python을 사용하다 보면 class라는 문법을 자주 만나게 됩니다.

간단한 프로그램에서는 함수와 기본 자료형만으로도 충분히 코드를 작성할 수 있지만, 프로그램의 규모가 커지면 데이터를 하나로 묶고 그 데이터와 관련된 기능까지 함께 관리해야 하는 경우가 많습니다.

이때 사용하는 것이 클래스(Class)입니다.

클래스는 처음 보면 __init__(), self 같은 문법 때문에 어렵게 느껴질 수 있습니다. 하지만 클래스가 무엇인지부터 차근차근 이해하면 생각보다 구조는 간단합니다.

이번 글에서는 Python 클래스의 기본 개념부터 객체와 인스턴스의 차이, __init__(), self, 인스턴스 변수와 메서드까지 살펴보겠습니다.

클래스(Class)란?

클래스는 쉽게 말하면 객체를 만들기 위한 설계도입니다.

예를 들어 사람을 표현하는 프로그램을 만든다고 생각해보겠습니다.

사람마다 이름과 나이는 다르지만, 기본적으로 다음과 같은 정보를 가지고 있습니다.

사람
├── 이름
├── 나이
└── 자기소개하기

이런 구조를 하나의 클래스로 정의할 수 있습니다.

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"{self.name}, {self.age}살입니다.")

여기서 Person이 클래스입니다.

이 클래스는 사람이라는 객체가 어떤 데이터를 가지고 있고 어떤 기능을 수행할 수 있는지를 정의합니다.

하지만 Person이라는 클래스를 정의했다고 해서 실제 사람이 만들어진 것은 아닙니다.

클래스를 이용해서 실제 객체를 생성해야 합니다.

객체(Object) 만들기

클래스로부터 객체를 만드는 방법은 다음과 같습니다.

person1 = Person("철수", 20)
person2 = Person("영희", 25)

이제 person1과 person2라는 두 개의 객체가 만들어졌습니다.

각각의 객체는 서로 다른 데이터를 가지고 있습니다.

print(person1.name)
print(person1.age)

print(person2.name)
print(person2.age)

결과:

철수
20
영희
25

같은 Person 클래스를 사용했지만 각각 독립적인 데이터를 가지고 있습니다.

즉,

Person 클래스
      ↓
 ┌───────────┐
 ↓           ↓
person1     person2
철수, 20     영희, 25

와 같은 구조라고 생각하면 이해하기 쉽습니다.

클래스와 객체의 관계

클래스와 객체의 관계를 간단하게 표현하면 다음과 같습니다.

클래스
  ↓
객체 생성
  ↓
객체 1
객체 2
객체 3
...

클래스가 설계도라면 객체는 그 설계도를 사용해서 만들어진 실제 결과물이라고 생각할 수 있습니다.

예를 들어:

class Person:
    pass

라는 클래스를 만들었다면,

person1 = Person()
person2 = Person()

처럼 여러 개의 객체를 만들 수 있습니다.

각 객체는 서로 독립적으로 존재합니다.

인스턴스(Instance)란?

클래스를 공부하다 보면 객체와 함께 인스턴스(Instance)라는 단어도 자주 등장합니다.

예를 들어:

person = Person()

이라고 하면 person은 Person 클래스의 인스턴스라고 표현할 수 있습니다.

쉽게 말하면 클래스와 객체의 관계를 조금 더 구체적으로 표현한 것이 인스턴스입니다.

Person 클래스
      ↓
Person()을 통해 생성
      ↓
person 인스턴스

따라서 일반적으로 다음과 같이 이해하면 됩니다.

  • 클래스: 객체를 만들기 위한 설계도
  • 객체: 클래스를 통해 만들어진 대상
  • 인스턴스: 특정 클래스에서 만들어진 객체

실제로 Python에서는 객체와 인스턴스를 비슷한 의미로 사용하는 경우가 많습니다.

다만 “어떤 클래스의 인스턴스인가?”라는 관계를 강조할 때 인스턴스라는 표현을 사용합니다.

__init__()이란?

클래스를 정의할 때 다음과 같은 메서드를 자주 사용합니다.

def __init__(self, name, age):
    self.name = name
    self.age = age

__init__()은 객체가 생성될 때 초기화 작업을 수행하는 특수 메서드입니다.

예를 들어 다음 코드를 실행하면:

person = Person("철수", 20)

Python은 객체를 생성하면서 __init__()을 호출합니다.

전달한 "철수"와 20은 각각 name, age에 전달됩니다.

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

따라서 다음과 같이 객체가 초기화됩니다.

person
 ├── name → "철수"
 └── age  → 20

이처럼 __init__()은 객체가 처음 만들어질 때 필요한 값을 설정하는 데 주로 사용합니다.

self는 무엇일까?

Python 클래스를 처음 배울 때 가장 헷갈리는 부분 중 하나가 self입니다.

다음 코드를 보겠습니다.

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

여기서 self는 현재 만들어지고 있는 객체 자신을 가리키는 참조라고 이해하면 됩니다.

예를 들어:

person1 = Person("철수", 20)

라고 하면 self는 person1 객체를 가리키게 됩니다.

그리고:

self.name = name

은 결국 다음과 같은 의미가 됩니다.

person1.name = "철수"

다시:

person2 = Person("영희", 25)

를 실행하면 이번에는 self가 person2를 가리킵니다.

person2.name = "영희"

그래서 같은 클래스에서 만들어진 객체라도 서로 다른 값을 가질 수 있습니다.

인스턴스 변수란?

다음과 같은 코드를 살펴보겠습니다.

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

여기서:

self.name
self.age

를 인스턴스 변수라고 합니다.

각 객체가 독립적으로 가지고 있는 데이터이기 때문입니다.

예를 들어:

person1 = Person("철수", 20)
person2 = Person("영희", 25)

라면,

person1
 ├── name → 철수
 └── age  → 20

person2
 ├── name → 영희
 └── age  → 25

처럼 각각 다른 값을 저장합니다.

따라서 다음과 같이 값을 변경할 수도 있습니다.

person1.age = 21

print(person1.age)
print(person2.age)

결과:

21
25

person1의 값만 변경되고 person2에는 영향을 주지 않습니다.

인스턴스 메서드란?

클래스 안에 정의된 함수는 일반적으로 메서드(Method)라고 부릅니다.

예를 들어:

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"{self.name}, {self.age}살입니다.")

여기서:

def introduce(self):

가 메서드입니다.

객체를 만든 다음 호출할 수 있습니다.

person = Person("철수", 20)

person.introduce()

결과:

철수, 20살입니다.

메서드 내부에서 self.name과 self.age를 사용할 수 있는 이유는 self가 현재 객체를 가리키고 있기 때문입니다.

self는 직접 전달해야 할까?

다음 코드에서 조금 이상한 부분이 있을 수 있습니다.

person.introduce()

introduce()에는 self가 필요한데 호출할 때 전달하지 않았습니다.

그런데 실제로는 문제가 없습니다.

Python이 메서드를 호출할 때 현재 객체를 자동으로 전달하기 때문입니다.

개념적으로 다음과 비슷하게 이해할 수 있습니다.

person.introduce()

↓

Person.introduce(person)

즉 self는 메서드가 어떤 객체에 대해 동작해야 하는지 알려주는 역할을 합니다.

클래스 안에서 여러 메서드 만들기

하나의 클래스에는 여러 개의 메서드를 만들 수 있습니다.

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"이름: {self.name}")
        print(f"나이: {self.age}")

    def increase_age(self):
        self.age += 1

사용하면:

person = Person("철수", 20)

person.introduce()

person.increase_age()

print(person.age)

결과:

이름: 철수
나이: 20
21

이처럼 클래스는 데이터와 그 데이터를 처리하는 기능을 하나로 묶어서 관리할 수 있습니다.

함수로 작성하는 것과 무엇이 다를까?

간단한 프로그램이라면 클래스를 사용하지 않고 함수만으로도 충분히 작성할 수 있습니다.

예를 들어:

name = "철수"
age = 20

def introduce(name, age):
    print(f"{name}, {age}살입니다.")

하지만 관리해야 하는 사람이 많아지면 데이터와 함수가 따로 흩어질 수 있습니다.

클래스를 사용하면 관련된 데이터와 기능을 하나로 묶을 수 있습니다.

class Person:

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def introduce(self):
        print(f"{self.name}, {self.age}살입니다.")

그리고 각 객체가 자신의 데이터를 관리하도록 만들 수 있습니다.

person1 = Person("철수", 20)
person2 = Person("영희", 25)

person1.introduce()
person2.introduce()

이런 방식은 프로그램의 규모가 커질수록 관리하기 편해집니다.

클래스는 왜 사용하는가?

클래스를 사용하는 가장 큰 이유 중 하나는 관련된 데이터와 기능을 하나의 단위로 묶어서 관리하기 위해서입니다.

예를 들어 자동차를 프로그램으로 표현한다고 생각해보겠습니다.

자동차에는 다음과 같은 데이터가 있을 수 있습니다.

자동차
├── 브랜드
├── 색상
├── 속도
└── 연식

그리고 다음과 같은 기능도 있을 수 있습니다.

시동 걸기
가속하기
감속하기
정지하기

이것을 하나의 클래스로 표현할 수 있습니다.

class Car:

    def __init__(self, brand, color):
        self.brand = brand
        self.color = color
        self.speed = 0

    def accelerate(self):
        self.speed += 10

    def brake(self):
        self.speed -= 10

객체를 만들면:

car = Car("Hyundai", "black")

이제 car 객체가 자신의 브랜드, 색상, 속도와 관련된 기능을 함께 관리하게 됩니다.

car.accelerate()
car.accelerate()

print(car.speed)

결과:

20

이처럼 클래스는 현실 세계의 대상을 프로그램 안에서 표현하거나, 서로 관련된 데이터와 기능을 하나의 구조로 관리할 때 유용합니다.

클래스 기본 구조 정리

지금까지 배운 내용을 가장 기본적인 형태로 정리하면 다음과 같습니다.

class 클래스이름:

    def __init__(self, 값):
        self.변수 = 값

    def 메서드이름(self):
        # 기능
        pass

그리고 객체를 생성합니다.

객체 = 클래스이름(값)

객체의 변수에 접근할 때는:

객체.변수

메서드를 호출할 때는:

객체.메서드()

를 사용합니다.

전체적인 관계는 다음과 같습니다.

             클래스
               │
        ┌──────┴──────┐
        ↓             ↓
     객체 1          객체 2
        │             │
   ┌────┴────┐   ┌────┴────┐
   이름       나이 이름       나이
   철수       20   영희       25

마무리

Python의 클래스는 처음에는 self와 __init__() 때문에 조금 낯설 수 있습니다.

하지만 기본적인 구조는 생각보다 단순합니다.

클래스는 객체를 만들기 위한 구조를 정의하고, 객체는 그 클래스를 이용해 실제로 만들어진 대상입니다.

그리고 객체는 자신의 데이터를 인스턴스 변수로 가지고 있으며, 클래스 내부의 메서드를 통해 그 데이터를 처리할 수 있습니다.

이번 글에서 기억해야 할 핵심은 다음과 같습니다.

  • class는 객체를 만들기 위한 구조를 정의한다.
  • 클래스에서 만들어진 객체를 인스턴스라고 부른다.
  • __init__()은 객체가 생성될 때 초기화 작업을 수행한다.
  • self는 현재 객체를 가리킨다.
  • self.name, self.age와 같은 값은 인스턴스 변수다.
  • 클래스 안에 정의한 함수는 메서드라고 한다.
  • 클래스는 관련된 데이터와 기능을 하나로 묶어 관리할 수 있다.

다음 글에서는 클래스에서 사용할 수 있는 인스턴스 메서드, 클래스 메서드, 정적 메서드를 비교하면서 각각 self, cls, @staticmethod가 어떤 차이를 가지고 있는지 살펴보겠습니다.

jiji

AI, Python, 생활정보와 정부 정책 정보를 쉽게 설명하는 정보 블로그입니다.

Ad Placeholder
Scroll to Top