카테고리 없음

6-4. 클래스 변수, 정적 메서드, 클래스 메서드

Python_Basic 2025. 6. 30. 21:28

파이썬 클래스 변수, 정적 메서드, 클래스 메서드

안녕하세요! 지난 시간에는 객체지향 프로그래밍의 핵심인 생성자(__init__)와 인스턴스 변수에 대해 알아보았습니다. 이제 각 객체(인스턴스)가 자신만의 고유한 데이터(속성)를 가질 수 있다는 것을 이해하셨죠! 또한 객체가 특정 행동을 수행하는 메서드에 대해서도 학습했습니다.

이번 시간에는 클래스에 속하지만, 특정 객체(인스턴스)와는 조금 다르게 동작하는 특별한 변수와 메서드들에 대해 알아보겠습니다. 바로 클래스 변수(Class Variable), 정적 메서드(Static Method), 그리고 **클래스 메서드(Class Method)**입니다.

이들을 이해하면 파이썬 클래스를 더욱 유연하고 효율적으로 설계할 수 있습니다.


Part 1: 클래스 변수 (Class Variable) - 모든 객체가 공유하는 데이터

클래스 변수는 클래스 내부에 정의되지만, __init__ 메서드나 다른 메서드 내부에 정의되지 않고 클래스 자체에 직접 정의되는 변수입니다. 이 변수는 해당 클래스로부터 생성된 모든 객체(인스턴스)들이 공유하는 데이터입니다.

1. 클래스 변수 정의 및 접근

  • 정의: 클래스 블록의 최상단에 일반 변수처럼 정의합니다.
  • 접근:
    • 클래스이름.변수이름으로 직접 접근하는 것이 가장 일반적이고 권장됩니다.
    • 객체이름.변수이름으로도 접근할 수 있지만, 값을 변경할 때 주의해야 합니다.

예시: Student 클래스에 school_name 클래스 변수 추가

Python
 
# 파일 이름: class_variable.py

class Student:
    # 클래스 변수 (모든 Student 객체가 공유)
    school_name = "파이썬 대학교"
    student_count = 0 # 전체 학생 수 (클래스 변수로 관리)

    def __init__(self, name, student_id):
        self.name = name          # 인스턴스 변수
        self.student_id = student_id # 인스턴스 변수
        Student.student_count += 1 # 객체 생성될 때마다 클래스 변수 증가

    def introduce(self):
        # 인스턴스 변수와 클래스 변수 모두 사용
        print(f"안녕하세요, 저는 {self.school_name} 학생 {self.name}입니다. 학번은 {self.student_id}입니다.")

# 객체 생성
s1 = Student("김철수", "2023001")
s2 = Student("이영희", "2023002")

s1.introduce()
s2.introduce()

# 클래스 변수에 접근
print(f"\n현재 학교 이름: {Student.school_name}")
print(f"총 학생 수: {Student.student_count}")

# 클래스 변수 값 변경 (클래스 이름으로 변경)
Student.school_name = "구글 개발자 아카데미"
print(f"\n학교 이름 변경 후: {Student.school_name}")

# 변경된 클래스 변수는 모든 객체에 반영됩니다.
s1.introduce()
s2.introduce()
  • school_name과 student_count는 Student 클래스에 직접 속해 있으며, s1, s2와 같은 모든 Student 객체가 이 값을 공유합니다.
  • Student.student_count += 1처럼 클래스 변수를 변경할 때는 **클래스 이름(Student)**을 사용하는 것이 좋습니다. s1.student_count += 1처럼 객체 이름으로 변경하려 하면 s1 객체에 새로운 student_count라는 인스턴스 변수가 생성되어 클래스 변수와는 다른 변수가 되는 경우가 생길 수 있습니다.

 

[VS Code 터미널 출력]

파이썬 클래스 변수 정의, 접근, 변경 예시

Part 2: 정적 메서드 (Static Method) - 객체나 클래스 데이터에 독립적인 유틸리티 함수

정적 메서드는 클래스 내부에 정의되지만, 객체(인스턴스)의 데이터(self)나 클래스의 데이터(cls)에는 접근할 필요가 없는 독립적인 유틸리티 함수입니다. 논리적으로는 클래스와 관련이 있지만, 특정 객체의 상태에 의존하지 않는 함수일 때 사용합니다.

1. 정적 메서드 정의 및 호출

  • 정의: 메서드 위에 @staticmethod 데코레이터를 붙여 정의합니다. 첫 번째 매개변수로 self나 cls를 받지 않습니다.
  • 호출: 클래스이름.메서드이름() 또는 객체이름.메서드이름()으로 호출합니다.

예시: MathUtils 클래스에 add 정적 메서드 추가

Python
 
# 파일 이름: static_method.py

class MathUtils:
    @staticmethod # 정적 메서드를 나타내는 데코레이터
    def add(x, y):
        """두 숫자를 더하는 정적 메서드"""
        return x + y

    @staticmethod
    def is_positive(number):
        """숫자가 양수인지 확인하는 정적 메서드"""
        return number > 0

# 정적 메서드 호출 (클래스 이름으로 호출하는 것이 일반적)
sum_result = MathUtils.add(10, 5)
print(f"10 + 5 = {sum_result}")

is_pos = MathUtils.is_positive(-3)
print(f"-3은 양수인가? {is_pos}")

# 객체를 통해서도 호출은 가능하나, 권장되지 않습니다.
# calc = MathUtils()
# sum_result_obj = calc.add(20, 10)
# print(f"객체로 호출 (권장X): {sum_result_obj}")
  • add와 is_positive 메서드는 self 매개변수를 받지 않습니다. 이들은 MathUtils 클래스 안에 있지만, 특정 MathUtils 객체의 상태를 변경하거나 접근하지 않습니다. 단순히 입력받은 값으로 계산만 수행합니다.

 

[VS Code 터미널 출력]

파이썬 정적 메서드(@staticmethod) 사용 예시

Part 3: 클래스 메서드 (Class Method) - 클래스 자체에 접근하는 메서드

클래스 메서드는 클래스 내부에 정의되지만, 첫 번째 매개변수로 **클래스 자체(cls)**를 받는 특별한 메서드입니다. 이를 통해 클래스 메서드는 클래스 변수에 접근하거나, 클래스를 사용하여 새로운 객체를 생성하는 등의 작업을 수행할 수 있습니다.

1. 클래스 메서드 정의 및 호출

  • 정의: 메서드 위에 @classmethod 데코레이터를 붙여 정의합니다. 첫 번째 매개변수는 관례적으로 cls라고 이름 붙입니다.
  • 호출: 클래스이름.메서드이름() 또는 객체이름.메서드이름()으로 호출합니다.

예시: Product 클래스에 total_products 클래스 변수와 from_string 클래스 메서드 추가

Python
 
# 파일 이름: class_method.py

class Product:
    # 클래스 변수 (전체 제품 수)
    total_products = 0

    def __init__(self, name, price):
        self.name = name       # 인스턴스 변수
        self.price = price     # 인스턴스 변수
        Product.total_products += 1 # 객체 생성 시 클래스 변수 증가

    def display_info(self):
        print(f"상품명: {self.name}, 가격: {self.price}원")

    @classmethod # 클래스 메서드를 나타내는 데코레이터
    def get_total_products(cls): # 첫 번째 매개변수로 cls를 받음
        """현재까지 생성된 총 제품 수를 반환하는 클래스 메서드"""
        return cls.total_products # cls.total_products로 클래스 변수에 접근

    @classmethod
    def from_string(cls, product_string): # 대체 생성자 역할
        """'이름-가격' 문자열에서 제품 객체를 생성하는 클래스 메서드"""
        name, price_str = product_string.split('-')
        price = int(price_str)
        return cls(name, price) # cls()를 사용하여 새로운 객체 생성

# 객체 생성
p1 = Product("텀블러", 15000)
p2 = Product("무선 이어폰", 120000)

p1.display_info()
p2.display_info()

# 클래스 메서드 호출 (클래스 이름으로 호출하는 것이 일반적)
print(f"\n현재까지 생성된 총 제품 수: {Product.get_total_products()}개")

# 클래스 메서드를 대체 생성자로 사용
product_from_str = Product.from_string("책상-80000")
product_from_str.display_info()
print(f"총 제품 수 업데이트: {Product.get_total_products()}개")
  • get_total_products(cls): cls.total_products를 통해 Product.total_products 클래스 변수에 접근합니다. cls는 여기서 Product 클래스 자체를 의미합니다.
  • from_string(cls, product_string): 문자열을 파싱하여 name과 price를 추출한 후, return cls(name, price)를 통해 Product(name, price)와 동일하게 새로운 Product 객체를 생성하여 반환합니다. 이는 딕셔너리나 다른 형식의 데이터로부터 객체를 생성하는 '공장' 역할을 할 수 있습니다.

 

[VS Code 터미널 출력]

파이썬 클래스 메서드(@classmethod) 사용 예시

Part 4: 인스턴스, 클래스, 정적 요소 비교 및 활용 시기

파이썬 클래스 내부에서 다루는 변수와 메서드의 종류를 정리해봅시다.

구분 첫 번째 매개변수 접근 대상 주요 용도 예시
인스턴스 변수 self.변수이름 객체 고유의 데이터 각 객체의 상태/속성 저장 self.name, self.age
클래스 변수 클래스이름.변수이름 모든 객체가 공유하는 데이터 클래스 전체에 공통된 정보, 상수를 관리 Class.total_count
인스턴스 메서드 self 객체 인스턴스 데이터 객체의 행동 정의, 객체 상태 변경 및 접근 self.introduce(), self.add_item()
정적 메서드 없음 (@staticmethod) 객체/클래스 데이터에 독립적 유틸리티 함수, 클래스와 논리적으로 관련 있지만 특정 객체 상태와 무관한 기능 Math.add(x, y)
클래스 메서드 cls (@classmethod) 클래스 자체, 클래스 변수 클래스 변수 조작, 대체 생성자, 클래스 팩토리 cls.get_count(), cls.from_string()
Sheets로 내보내기

언제 무엇을 사용해야 할까?

  • 인스턴스 변수/메서드: 각 객체마다 다른 값을 가지고, 그 객체만의 고유한 행동을 수행해야 할 때. (가장 흔하게 사용)
  • 클래스 변수: 모든 객체가 동일한 값을 공유해야 할 때, 또는 해당 클래스 전체에 대한 정보를 관리할 때. (예: 생성된 객체의 총 개수, 공통 설정)
  • 정적 메서드: 클래스 안에 함수를 넣고 싶지만, 그 함수가 객체의 상태(self)나 클래스 자체(cls)와는 독립적으로 작동하며 단순히 입력값을 처리하는 유틸리티일 때.
  • 클래스 메서드: 클래스 변수를 다루거나, 클래스 자체를 사용하여 새로운 객체를 생성하는 '공장' 역할을 하는 함수가 필요할 때.

마무리하며

이번 시간에는 파이썬 객체지향 프로그래밍에서 객체뿐만 아니라 클래스 수준에서 데이터를 관리하고 행동을 정의하는 방법들을 알아보았습니다.

  • 클래스 변수: 모든 객체가 공유하는 데이터.
  • 정적 메서드 (@staticmethod): self나 cls 없이 독립적으로 동작하는 유틸리티 함수.
  • 클래스 메서드 (@classmethod): cls를 통해 클래스 자체에 접근하고 클래스 변수를 다루거나 대체 생성자 역할을 하는 함수.

이러한 개념들은 파이썬에서 더욱 구조적이고 효율적인 객체지향 프로그램을 설계하는 데 필수적인 도구입니다. 각각의 목적과 활용 시점을 잘 이해하는 것이 중요합니다.

다음 포스팅에서는 객체지향 프로그래밍의 핵심 원칙 중 하나인 **상속(Inheritance)과 다형성(Polymorphism)**에 대해 자세히 알아보겠습니다.


궁금한 점이 있다면 언제든지 질문해주세요! 다음 포스팅에서 만나요!

반응형