[Python] OOP(4): 클래스변수, 클래스메서드, 정적메서드

#1 클래스 변수

클래스 변수는 인스턴스 변수와 달리 클래스 전반에 영향을 미치는 변수다. 인스턴스들은 클래스 이름을 통해 클래스 변수에 접근할 수 있다.

class MyClass:

    # 클래스 변수 정의
    class_var = "Class variable"

    def __init__(self, value):
        self.inst_var = value

    def print(self):
            # 클래스 이름을 통해 클래스 변수에 접근
        print(MyClass.class_var, self.inst_var)

print(MyClass.class_var)  # Class variable

i1 = MyClass(123)
i2 = MyClass(456)
i3 = MyClass(789)

i1.print()  # Class variable 123
i2.print()  # Class variable 456
i3.print()  # Class variable 789

하나의 인스턴스에서 클래스 변수를 바꾸면 모든 인스턴스가 영향을 받는다.

class MyClass:

    class_var = "Class variable"

    def __init__(self, value):
        self.inst_var = value

    def change_class_var(self, new_value):
        MyClass.class_var = new_value
        # class_var = new_value 는 지역변수
        # self.class_var = new_value는 새로운 인스턴스 변수 생성

    def print(self):
        print(MyClass.class_var, self.inst_var)

i1 = MyClass(123)
i2 = MyClass(456)

i1.print()  # Class variable 123
i2.print()  # Class variable 456

i2.change_class_var("Changed")

i1.print()  # Changed 123
i2.print()  # Changed 456

#2 클래스 메서드

클래스 메서드는 클래스 전체에 영향을 미친다. 클래스에 대한 변화는 모든 인스턴스에게 미치기 때문이다. 클래스 정의에서 @classmethod 데코레이터가 있으면 클래스 메서드다.

class MyClass:

    class_var = "Class variable"

    def __init__(self, value):
        self.inst_var = value

    def print(self):
        print(MyClass.class_var, self.inst_var)

    @classmethod
    def change_class_var(cls, new_value):
        cls.class_var = new_value
        # self ?

i1 = MyClass(123)
i2 = MyClass(456)

# 인스턴스에서 클래스 메써드 사용
i2.change_class_var("Changed")

i1.print()
i2.print()

# 클래스 이름으로 클래스 메써드 사용
MyClass.change_class_var("Changed again")

i1.print()
i2.print()

클래스 메서드의 첫번째 매개변수는 클래스 자신이다. cls을 사용한다.

#3 정적 메서드

정적 메서드는 일반메서드나 클래스 메서드와 달리 아무런 영향을 미치지 않는다. 하지만 해당 자료형들이 데이터를 바꿀 필요 없이 기능을 수행해야할 필요가 있는 경우에 편의상 사용한다. @staticmethod 데코레이터로 정의한다.

class MyClass:
    def __init__(self, value):
        self.inst_var = value

    # 파이썬이 self나 cls를 자동으로 넣어주지 않습니다.
    @staticmethod
    def static_print():
        print("Hello, World!")

        # 클래스 변수를 사용할 경우에는
        # 클래스 메써드로 만드는 것을 권장
        # MyClass.cls_var = 123

i1 = MyClass(123)
i2 = MyClass(456)

MyClass.static_print()

i1.static_print()
i2.static_print()

매개변수에 self 나 cls가 없는게 특징이다. 둘 중에 하나라도 매개변수가 필요하다면 정적메서드로 정의하는 대신에 일반 메서드나 클래스 메서드로 정의하는 것이 낫다.