Programming/Python

[Python 3.7] 파이썬 정적 메소드 vs 클래스 메소드 (staticmethod vs classmethod)

Nirsa 2020. 2. 6. 23:34
반응형

 

  • 정적 메소드 vs 클래스 메소드

정적 메소드(staticmethod)와 클래스 메소드(classmethod)는 인스턴스를 생성하고 호출하는 방식이 아니라, 클래스에서 바로 호출할 수 있습니다.

class test:
    def instance_add(self, a, b):
        return a + b

    @staticmethod
    def static_add(a, b):
        return a + b

    @classmethod
    def class_add(cls, a, b):
        return a + b

# 인스턴스 호출
a = test
print(a.instance_add(None, 1, 1))

# 스태틱 메소드 호출
print(test.static_add(2, 2))

# 클래스 메소드 호출
print(test.class_add(3, 3))

정적 메소드와 클래스 메소드는 위의 코드와 같이 메소드 위에 @staticmethod , @classmethod를 붙여 주어야 합니다. @를 앞에 붙이는 것은 데코레이터(decorator)라고 하는데, 추후 업로드 할 예정 입니다.

또한 정적 메소드는 self를 사용할 필요가 없으며 클래스 메소드는 cls를 사용하여 클래스 속성을 인자로 전달 받습니다.(무조건 cls를 써야하는건 아니지만 관례적으로 cls를 사용 합니다) 위의 코드만으로 봣을 땐 차이가 없어 보이는데, 클래스를 상속 받을 때 차이가 발생 합니다.

아래는 Linux 클래스는 Windows 클래스를 상속받아 모든 코드를 실행시킬 수 있습니다. (상속 개념은 후에 업로드 예정 입니다) 이때 클래스 메소드는 cls로 현재 자기가 실행된 클래스 속성을 가져오고, 정적 메소드는 부모 클래스(Windows)의 속성을 가져오게 됩니다.

class Windows:
    os = "window10"		# 클래스 속성

    def __init__(self):
        self.out = "OS: " + self.os
        
    @staticmethod
    def static_os():
        return Windows()

    @classmethod
    def class_os(cls):
        return cls()

    def os_output(self):
        print(self.out)

class Linux(Windows):
    os = "Linux"		# 클래스 속성

a = Linux.static_os()
a.os_output()

b = Linux.class_os()
b.os_output()

결과값 : OS: window10
결과값 : OS: Linux

 

위의 코드가 조금 복잡하다면 좀 더 쉬운 코드로 확인해 봅시다. 아래 코드는 부모 클래스와 자식 클래스를 최소화 시켰고 각각 부모 클래스(parent_class)의 속성은 test = 'parent' 으로, 자식 클래스(child_class)의 속성은 test = 'child' 로 할당 해두었습니다.

클래스 메소드는 상속 관계를 이용해 자식 클래스로 접근(child_class.output())할 경우 클래스 메소드로 지정한 output의 return cls.test (자기 자신의 test 클래스 속성)에 의해 자식 클래스의 속성을 가지고 오는것을 확인할 수 있습니다. 즉, 클래스 메소드(classmethod)는 cls를 이용해 자기의 클래스 속성을 가져오며 자식 클래스로 접근할 경우 자식 클래스의 속성을 가져오고, 정적 메소드(staticmethod)는 부모의 클래스만을 가져 옵니다.

class parent_class:
    test = 'parent'

    @classmethod
    def output(cls):
        return cls.test

class child_class(parent_class):
    test = 'child'

print(child_class.output())
결과값 : child

 

위와 같이 상속 관계에서 가져오는 클래스 속성의 값이 다른게 클래스 메소드와 정적 메소드의 가장 큰 차이점이라고 생각 합니다. (사실 정적 메소드는 굳이... 왜 사용하는지 잘 모르겠습니다.)

 

반응형