메뉴 닫기

파이썬 클래스 변수와 인스턴스 변수의 차이 완벽 정리

파이썬 클래스 변수와 인스턴스 변수의 차이 완벽 정리

🐍 헷갈리는 self와 cls, 이제 정확히 이해하세요!

파이썬을 배우다 보면 클래스와 객체 개념은 피할 수 없는 기본기 중 하나입니다.
특히 클래스 변수와 인스턴스 변수의 차이는 초보자들이 자주 혼동하는 부분이기도 하죠.
self, cls 같은 키워드도 처음에는 너무 헷갈려서 막막하게 느껴질 수 있습니다.
하지만 개념만 정확히 정리하면 생각보다 단순하고 명확합니다.
오늘은 그 차이를 쉽고 명확하게 설명드릴게요.

이 글에서는 파이썬 클래스에서 변수의 종류를 구분하는 방법과,
클래스 변수와 인스턴스 변수가 메모리에서 어떻게 다르게 동작하는지를 알려드립니다.
또한 self와 cls의 의미도 간단한 예제를 통해 이해하기 쉽게 설명하니 끝까지 읽어보시면 큰 도움이 될 거예요.



🔗 클래스 변수와 인스턴스 변수의 정의

파이썬 클래스에서 변수를 정의할 때, 그 위치와 선언 방식에 따라 두 가지로 나뉩니다.
바로 클래스 변수인스턴스 변수입니다.
이 둘은 동작 방식부터 메모리 공유 방식까지 전혀 다르게 작동합니다.
정확히 이해하지 않으면 코딩하면서 예상치 못한 결과를 마주할 수 있어요.

먼저 클래스 변수는 클래스 내부에서 메서드 밖에 정의되며,
클래스가 생성한 모든 인스턴스가 이 변수를 공유합니다.
즉, 한 번 값을 바꾸면 모든 객체에 영향을 미치는 전역적인 속성이 되는 셈이죠.

반면 인스턴스 변수는 self를 통해 메서드 내부에서 정의되며,
객체가 생성될 때마다 독립적으로 만들어집니다.
따라서 객체마다 서로 다른 값을 가질 수 있어, 객체 고유의 상태를 표현할 때 주로 사용됩니다.

💡 TIP: 클래스 변수는 클래스 이름을 통해 접근하고, 인스턴스 변수는 객체를 통해 접근해야 합니다.

CODE BLOCK
class Car:
    wheels = 4  # 클래스 변수

    def __init__(self, color):
        self.color = color  # 인스턴스 변수

a = Car('red')
b = Car('blue')

print(a.wheels)   # 4
print(b.wheels)   # 4
print(a.color)    # red
print(b.color)    # blue

위 코드에서 wheels는 모든 자동차에 공통된 속성으로, 클래스 변수로 설정되어 있습니다.
반면 color는 각 자동차 인스턴스마다 다르게 설정되는 인스턴스 변수죠.
이처럼 클래스 변수와 인스턴스 변수는 사용 목적이 분명히 다르며, 이를 구분하는 것이 객체 지향 프로그래밍의 핵심입니다.

🛠️ self와 cls의 차이점

파이썬에서 클래스나 객체의 멤버에 접근할 때 자주 등장하는 키워드가 바로 selfcls입니다.
이 두 키워드는 각각 인스턴스와 클래스 자신을 가리키는 역할을 하며, 메서드의 성격에 따라 함께 사용됩니다.

self는 인스턴스 메서드에서 사용되며, 객체 자신(즉, 인스턴스)을 참조합니다.
self를 통해 인스턴스 변수에 접근하거나 메서드를 호출할 수 있습니다.
반면, cls는 클래스 메서드에서 사용되며, 클래스 자체를 가리키는 참조자입니다.
클래스 변수나 클래스 메서드에 접근할 때 주로 사용됩니다.

💬 self는 객체 중심, cls는 클래스 중심의 접근을 위한 키워드입니다.

CODE BLOCK
class Dog:
    species = "Canine"  # 클래스 변수

    def __init__(self, name):
        self.name = name  # 인스턴스 변수

    def show_name(self):  # 인스턴스 메서드
        print("Name:", self.name)

    @classmethod
    def show_species(cls):  # 클래스 메서드
        print("Species:", cls.species)

a = Dog("Max")
a.show_name()      # Name: Max
Dog.show_species() # Species: Canine

위 코드에서 show_name 메서드는 self를 통해 각 인스턴스의 이름에 접근하며,
show_species는 cls를 통해 클래스 변수 species에 접근합니다.
이처럼 self와 cls는 서로 다른 스코프를 다루기 때문에 사용하는 맥락에 따라 구분해서 써야 합니다.

💡 TIP: @classmethod 데코레이터가 붙은 함수에는 self 대신 반드시 cls를 사용해야 오류가 나지 않습니다.



⚙️ 클래스 변수는 어떻게 공유되는가?

클래스 변수는 해당 클래스로 생성된 모든 인스턴스 간에 공유되는 값입니다.
이 말은 하나의 클래스를 기반으로 여러 개의 객체를 만들어도, 그 객체들이 모두 같은 클래스 변수에 접근하게 된다는 뜻입니다.

이러한 특성 덕분에 클래스 변수는 공통된 속성이나 전역 설정값을 관리하는 데 유용하게 쓰입니다.
예를 들어 생성된 인스턴스의 개수를 세거나, 전체 객체에 동일하게 적용될 정책이나 옵션을 저장하는 용도로 많이 활용됩니다.

CODE BLOCK
class Counter:
    count = 0  # 클래스 변수

    def __init__(self):
        Counter.count += 1

print(Counter.count)  # 0
a = Counter()
b = Counter()
print(Counter.count)  # 2

위 예제에서 count는 클래스 변수로, Counter 클래스가 인스턴스화될 때마다 1씩 증가합니다.
두 개의 객체가 생성되었기 때문에 count는 2가 되었고, 이 값은 모든 인스턴스에서 동일하게 접근 가능합니다.

⚠️ 주의: 인스턴스에서 클래스 변수에 값을 대입하면 그 순간 인스턴스 전용 변수로 분리되며, 클래스 변수와의 연결이 끊어집니다.

CODE BLOCK
class Sample:
    shared = []

a = Sample()
b = Sample()

a.shared.append(1)
b.shared.append(2)

print(a.shared)  # [1, 2]
print(b.shared)  # [1, 2]

shared 리스트는 클래스 변수로, 모든 인스턴스가 하나의 동일한 리스트를 공유합니다.
a와 b 모두 같은 리스트에 값을 추가하기 때문에 출력 결과도 완전히 동일하게 나타납니다.
이처럼 클래스 변수는 실수로 잘못 다루면 의도치 않게 모든 인스턴스에 영향을 줄 수 있으므로 조심해서 사용해야 해요.

🔌 인스턴스 변수의 독립성과 활용

인스턴스 변수는 객체가 생성될 때마다 독립적으로 할당되는 변수입니다.
이 변수는 각 인스턴스만의 고유 데이터를 저장하는 데 사용되며, 다른 인스턴스와는 전혀 영향을 주고받지 않습니다.

즉, 인스턴스 변수는 객체의 상태(state)를 표현하는 중요한 도구입니다.
클래스를 통해 다양한 객체를 만들 때, 객체마다 각기 다른 속성을 가질 수 있도록 만들어주는 것이죠.
이를 통해 클래스는 일종의 ‘템플릿’ 역할을 하게 되고, 인스턴스는 그 틀에 따라 실제 데이터를 담는 ‘개별 객체’가 되는 것입니다.

CODE BLOCK
class User:
    def __init__(self, username, email):
        self.username = username  # 인스턴스 변수
        self.email = email        # 인스턴스 변수

u1 = User("alice", "alice@example.com")
u2 = User("bob", "bob@example.com")

print(u1.username)  # alice
print(u2.username)  # bob

위 코드에서 usernameemail은 인스턴스 변수로, 각 User 객체에 독립적으로 존재합니다.
따라서 u1과 u2는 서로 다른 값을 가지며, 한 객체의 속성을 변경해도 다른 객체에는 전혀 영향을 미치지 않습니다.

  • 🛠️인스턴스 변수는 self.변수명 형식으로 정의합니다.
  • 📌객체를 생성할 때마다 메모리에 새로운 공간이 만들어집니다.
  • 🔒한 객체의 인스턴스 변수는 다른 객체와 완전히 분리되어 있습니다.

실무에서 클래스를 사용할 때, 대부분의 경우 클래스 변수보다 인스턴스 변수를 더 자주 사용합니다.
이는 객체지향의 핵심이 바로 각 객체가 고유한 속성과 상태를 가진다는 원칙에 기반하고 있기 때문입니다.



💡 실전 예제로 이해하는 클래스 변수와 인스턴스 변수

이론적인 설명만으로는 클래스 변수와 인스턴스 변수의 차이를 완전히 이해하기 어려울 수 있습니다.
그래서 이번에는 하나의 실전 예제를 통해 이 두 변수의 차이를 더욱 직관적으로 살펴보겠습니다.

아래는 동물원(Zoo) 클래스를 설계하고, 동물 객체를 생성하는 예제입니다.
이 코드에는 클래스 변수와 인스턴스 변수가 모두 등장하며, 어떤 역할을 하는지 명확히 확인할 수 있습니다.

CODE BLOCK
class Zoo:
    animal_count = 0  # 클래스 변수

    def __init__(self, name, species):
        self.name = name        # 인스턴스 변수
        self.species = species  # 인스턴스 변수
        Zoo.animal_count += 1   # 클래스 변수 수정

    def info(self):
        print(f"{self.name}은(는) {self.species}입니다.")

z1 = Zoo("사자", "포유류")
z2 = Zoo("앵무새", "조류")

z1.info()  # 사자은(는) 포유류입니다.
z2.info()  # 앵무새은(는) 조류입니다.

print("동물 수:", Zoo.animal_count)  # 동물 수: 2

여기서 animal_count는 클래스 변수로, 동물이 추가될 때마다 1씩 증가합니다.
이 값은 클래스 전체가 공유하므로 현재까지 생성된 동물의 총 수를 저장하는 용도로 적합합니다.

반면 namespecies는 각 동물 인스턴스만의 고유 정보를 저장하는 인스턴스 변수입니다.
z1과 z2는 서로 다른 값을 가지며, 독립적으로 동작합니다.

💎 핵심 포인트:
클래스 변수는 공통된 데이터를 저장하고, 인스턴스 변수는 개별 객체의 고유 데이터를 저장합니다. 사용 목적에 따라 적절히 선택해야 합니다.

실무에서는 두 변수 모두 유용하게 쓰이지만, 그 쓰임새를 명확히 구분하지 못하면 디버깅이 어려워질 수 있습니다.
따라서 클래스 설계 시 변수의 사용 목적을 먼저 생각하고,
공통 데이터는 클래스 변수,
객체 고유 데이터는 인스턴스 변수로 명확히 분리하는 습관이 중요합니다.

자주 묻는 질문 (FAQ)

클래스 변수와 인스턴스 변수는 왜 구분해야 하나요?
두 변수는 메모리 저장 위치와 공유 범위가 다르기 때문에 구분이 필요합니다.
잘못 사용하면 모든 인스턴스가 예상치 못한 값을 공유하게 되어 오류가 발생할 수 있습니다.
self 없이도 인스턴스 변수 만들 수 있나요?
불가능합니다.
self는 현재 인스턴스를 의미하기 때문에, self 없이 정의하면 클래스나 지역변수로 처리되어 인스턴스 변수로 기능하지 않습니다.
클래스 변수는 반드시 클래스 이름으로만 접근해야 하나요?
인스턴스를 통해서도 접근은 가능하지만, 값을 변경하면 인스턴스 변수로 바뀌게 되어 클래스 변수의 공유 특성이 사라집니다.
따라서 클래스 이름을 통해 접근하는 것이 안전합니다.
cls는 꼭 써야 하나요? 다른 이름도 되나요?
기술적으로는 다른 이름도 사용할 수 있지만, 관례상 cls를 사용하는 것이 코드 가독성과 유지보수에 좋습니다.
self는 꼭 첫 번째 인자로만 써야 하나요?
네, 인스턴스 메서드의 첫 번째 인자는 self여야 합니다.
이는 파이썬 내부적으로 메서드 호출 시 객체를 첫 인자로 전달하는 구조이기 때문입니다.
클래스 메서드와 static 메서드는 어떻게 다르죠?
클래스 메서드는 cls를 통해 클래스에 접근할 수 있고, static 메서드는 cls나 self 없이 독립적으로 동작합니다.
주로 클래스와 관련 없는 유틸리티성 함수에 static을 사용합니다.
인스턴스 변수로 클래스 변수와 같은 이름을 쓰면 어떻게 되나요?
인스턴스 변수로 덮어쓰게 됩니다.
이 경우 해당 인스턴스만의 독립적인 값이 생기며, 더 이상 클래스 변수와 연결되지 않습니다.
초보자에게는 어떤 변수부터 익히는 게 좋을까요?
인스턴스 변수가 객체지향의 기본 개념에 더 가까우므로 먼저 익히는 것을 추천합니다.
그 후 클래스 변수의 공유 개념을 익히면 더 수월하게 이해할 수 있습니다.

📌 클래스 변수와 인스턴스 변수, 헷갈렸다면 이제는 확실히 구분하세요

파이썬 객체지향 프로그래밍의 핵심은 클래스와 인스턴스의 관계를 올바르게 이해하는 데 있습니다.
그 중심에는 바로 클래스 변수와 인스턴스 변수의 개념이 있죠.
클래스 변수는 모든 인스턴스가 공유하는 공통 데이터를 위한 것이고,
인스턴스 변수는 각각의 객체가 고유하게 가지는 상태를 표현합니다.
self는 인스턴스를, cls는 클래스를 지칭한다는 원리만 명확히 이해하면,
복잡해 보이던 파이썬 클래스 설계가 한결 단순해집니다.
실전 예제와 다양한 케이스를 함께 살펴본 이번 글을 통해, 변수의 구분과 쓰임새가 훨씬 더 명확해졌길 바랍니다.
파이썬을 활용한 더 효율적이고 깔끔한 코드 작성을 위해 꼭 기억해두세요.


🏷️ 관련 태그 : 파이썬클래스, 클래스변수, 인스턴스변수, self와cls, 파이썬객체지향, 클래스메서드, 파이썬입문, 파이썬변수구조, 코드설계팁, 파이썬공부법