본문 바로가기
Language&Framework&Etc/Python

@staticmethod 와 @classmethod

by 머리올리자 2022. 3. 7.

@staticmethod 와 @classmethod

 

코드 분석을 하다가 staticmethod가 많이 보여 classmethod와 함께 정리해본다.

 

 공통점

정적메서드로써 클래스에 직접 접근할 수 있는 메서드

(보통은 클래스를 정의한다음 사용하려면 클래스 인스턴스 정의가 필요하다)

 

아래 코드를 보자

 

보통의 클래스(인스턴스 선언 후 사용)

class test_class:
    def __init__(self):
        return print("instance made")
    
    def test_output(self, num1, num2):
        return num1 + num2


# print(test_class.test_output(1, 2)) -> 사용 불가

cls_instance = test_class() # instance made
out = cls_instance.test_output(1, 2)
print(out) # 3

만약 주석 부분을 풀고 실행한다면 에러가 발생할 것이다.

 

정적메서드는 인스턴스를 생성하지 않아도 위 코드를 실행 가능하게 한다.

 

staticmethod를 사용했을 때 코드를 실행해보자.

class test_class:
    def __init__(self):
        return print("instance made")
    
    @staticmethod
    def test_output(num1, num2):
        return num1 + num2

# staticmethod
print(test_class.test_output(1, 2)) # 3

# original way
cls_instance = test_class() # instance made
print(cls_instance.test_output(1, 2)) # 3

원래 클래스를 사용했을 때와의 차이점을 봐보자.

 

일단 클래스 메서드에서 @staticmethod가 추가되었다.

 

또, self가 빠졌다.

 

그리고, 인스턴스를 생성하지 않아도 클래스의 메서드를 사용 가능하다.

(테스트겸 staticmethod를 선언하고 원래 방법대로 인스턴스 생성하여 메서드에 접근해봤는데도 잘 된다)

 

다음 classmethod를 봐보자.

class test_class:
    def __init__(self):
        return print("instance made")
    
    @classmethod
    def test_output(cls, num1, num2):
        return num1 + num2

# staticmethod
print(test_class.test_output(1, 2)) # 3

# original way
cls_instance = test_class() # instance made
print(cls_instance.test_output(1, 2)) # 3

클래스 메서드 안에 cls라는 인자가 추가되며

나머지는 staticmethod와 동일하게 사용가능하다는 것을 알 수 있다.

 

 차이점

공통점은 봤으니 차이점을 알아야지?

 

일단 변수 접근 방법부터 봐보자

 

 

변수 접근

(위에서 작성했던 __init__ 제거)

class test_class:
    var1 = 3
    
    @staticmethod
    def static_method(num1):
        return num1 + test_class.var1

    # cls로 변수 접근
    @classmethod
    def class_method1(cls, num2):
        return num2 + cls.var1

    # static 방법으로 접근
    @classmethod
    def class_method2(cls, num2):
        return num2 + test_class.var1

# staticmethod
print(test_class.static_method(1)) # 4
print(test_class.class_method1(1)) # 4
print(test_class.class_method2(1)) # 4

(1) staticmethod의 경우 test_class에 직접 접근하여 변수를 받아오고

(2) classmethod의 경우 cls를 이용하여 변수를 받아오고

(3) classmethod는 또한 staticmethod와 동일한 방법으로도 변수에 접근 가능하다.

 

상속

import paramiko


class parent_class:
    init = "부모 클래스"
    
    def __init__(self):
        self.value = self.init

    #######################
    @staticmethod 
    def static_method():
        return parent_class.init

    #######################
    @classmethod
    def class_method(cls):
        return cls().init


class child_class(parent_class):
    init = "자식 클래스"


print(child_class.static_method()) # 부모 클래스
print(child_class.class_method()) # 자식 클래스

위의 코드를 실행해보면

--

staticmethod는 부모클래스의 속성 값을

classmethod는 자식클래스의 속성 값을

--

가져온다.

 

모든 것이 그렇지만 위 정적메서드도 자기 목적에 맞게 사용하면 유용할 수 있을듯하다.

 

정리 했으니 다시 원래 코드 분석으로.....