본문 바로가기
Python

[Python] instance methods, class methods, and static methods

by ds31x 2023. 8. 20.

Instance Methods

instance를 통해 접근(=호출)되는 methods를 가르킴.
일반적인 methods가 바로 instance methods임.

 

method와 function의 차이점 중 하나로 애기되는

  • "정의될 때 첫번째 parameter가 self이면 method "라는 것은
  • 바로 instance methods 를 가르킴.
  • class method인 경우엔 성립하지 않음: 이 경우 첫번째 parameter가 class임.

method를 호출한 instance를 의미하는 self를 통해
instance variables (or instance attributes)에 접근가능하며 이들의 처리가 가능함.


Class Methods

instance가 아닌 class를 통해 접근되는 methods를 가르킴.

 

즉 다음과 같이 처리됨 (instance 명이 아닌 class명을 통해 호출됨.)

클래스이름.class_method()

 

일반적으로 해당 class의 모든 instance가 공유하고 있는 어떤 attributes를 수정하거나 접근해야하는 경우 많이 사용됨.
(instance 각각의 attributes가 아니라, 이들이 공유하는 class attributes와 관련된 처리를 수행하는 것이 class method임.)

 

class method의 특징은 다음과 같음.

  • 첫번째 parameter는 바로 class를 받게 됨. (instance를 나타낸 self가 아닌)
    • 때문에 해당 parameter의 이름을 관례적으로 cls라고 한다.
    • 사실 class method는 instance를 통해서도 호출이 가능함.
  • class methods는 class attributes에 접근하여 처리하는 데에 사용됨.
  • 구현 시 classmethod 데코레이터를 사용함.
class Test:

  cnt = 0  # class variable

  def __init__(self):
    self.ins_v = 0
    Test.cnt += 1

  @classmethod
  def get_Test_Cnt(cls):
    print(f'{type(cls)}: {isinstance(cls,Test)}')
    return Test.cnt

  # # manual로 class method로 만들기!
  # get_Test_cnt = classmethod(get_Test_Cnt())

a = Test()
print(Test.get_Test_Cnt())
b = Test()
print(Test.get_Test_Cnt())

# instance를 통해서도 호출이 가능함.
print(a.get_Test_Cnt())
  • instance method의 self 대신에 cls로 class를 넘겨받음.
  • instance 를 통해서도 호출이 가능함 (위의 code snippet의 마지막 라인 참고).
  • 보통 decorator @classmethod를 사용하여 구현함.

Static Methods

앞서 살펴본 instance method와 class method와 가장 큰 차이점을 가지는 Static Methods는

  • 필수적인 첫번째 argument가 없다.
  • 즉, argument로 instance나 class를 받지 않는다는 것임.

 

어찌 보면 function과 거의 비슷하다.
단지 차이점은 static methods는 class 정의 안에서 선언된다는 점 뿐이다.

 

instance와 달리 class와 관련된 attribute들에 접근하는 경우 사용된다.

이 때문에 class method와 매우 유사하다.
단 차이점은 첫번째 argument로 class가 넘어오지 않는다는 차이가 있음.

  • static methods는 class attribute에 접근하기 위해
  • 실제 코드에서 class 이름을 사용하여 attribute에 접근하기 때문에
  • inheritance등을 통해 다른 class로 상속된 경우 등에 대해 처리가 어려움.

아래의
Class methods와 Static methods의 차이점
에 대한 부분을 참고할 것.

 

static methods의 특징은 다음과 같음.

  • selfcls와 같은 필수적인 첫번째 parameter가 없음.
    • instance 이름 을 통한 method 호출의 경우, 해당 instance 이름이 첫번째 argument로 전달됨.
    • 때문에 static methods로 구현된 경우, instance를 통한 호출이 불가해짐.
  • class attributes에 접근하며, instance attributes에는 접근하지 않는다.
    • self가 없기 때문에 instatnce attributes에는 접근하지 못함.
    • cls도 없기 때문에 class명을 통해 class attributes에 접근한다.
    • instance들의 상태(=instance attributes)를 바꾸지 않는 pure function을 만드는데 주로 사용됨.
static method 는
class 자체 또는 그 instance와는 독립적이기 때문에,
특정 object의 상태에 종속되지 않는 범용적인 기능을 제공
하는데 사용됨
(PySide6의 QMessageBox.information 등등)

다음의 code snippet 은 Test라는 class의 인스턴스가 몇 개 생성되었는지를 관리하는 class attribute cnt가 있으며 static method get_Test_Cnt()를 통해 해당 값에 접근하는 예제임.

class Test:

  cnt = 0  # class variable

  def __init__(self):
    self.ins_v = 0
    Test.cnt += 1

  @staticmethod
  def get_Test_Cnt():
    return Test.cnt

  # # manual로 static method로 만들기!
  # get_Test_cnt = staticmethod(get_Test_Cnt())

a = Test()
print(Test.get_Test_Cnt())
b = Test()
print(Test.get_Test_Cnt())
  • static method의 경우, clsself를 parameter로 가지지 않으므로
    class attribute에 접근하기 위해 클래스이름을 이용한다.
  • return Test.cnt을 사용한 line을 확인.
  • 주로 @staticmethod decorator를 사용하여 static method로 만듬.

Class Methods vs. Static Methods

이 둘은 instance attributes가 아닌 class attributes에 접근할 때, 굳이 instance를 만들지 않고 접근하기 위해 사용되기 때문에 사용처가 유사하고 서로 대체해서 사용이 가능함.

하지만 static methods의 경우, 접근하는 class attributes를 code상에 명시적으로 기재해야하기 때문에 이를 상속 등으로 확장할 경우에는 사용이 어렵다.
반면 class methods의 경우, cls parameter로 현재의 class를 넘겨받기 때문에 이같은 경우 보다 유연하게 처리할 수 있음.

새로운 instance를 생성하여 반환하는 factory method를 구현할 경우,
class methods가 보다 유용하다.(보다 확장성이 있음)

 

다음 code snippet은 class attribute cnt에 대한 접근을 static method와 class method로 구현한 STest라는 클래스와 이를 상속받은 SSTest 클래스를 보여준다. 단, SSTest는 class attribute cnt의 값을 100으로 변경한 차이가 있음.

class STest:

  cnt = 0

  @staticmethod
  def get_cnt_through_sm():
    return STest.cnt

  @classmethod
  def get_cnt_through_cm(cls):
    return cls.cnt

class SSTest(STest):
  cnt = 100

print(f'static method : {SSTest.get_cnt_through_sm()}')
print(f'class method  : {SSTest.get_cnt_through_cm()}')
  • static method 로 접근시 STest.cnt로 고정이 된 상태이기 때문에 0이 출력됨.
  • class method로 접근하는 경우, cls로 현재의 class가 무엇인지를 알 수 있으므로 100이 출력됨.

결과는 다음과 같음.

static method : 0
class method  : 100

읽어보면 좋은 자료.

https://gist.github.com/dsaint31x/258d106bb0785c2f4d994adc295a07e2

 

py_static_methods_class_methods.ipynb

py_static_methods_class_methods.ipynb. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

2023.08.18 - [Python] - [Python] Decorator

 

[Python] Decorator

Python이 제공하는 Decorator는 기존의 function을 수정하지 않으면서 특정 처리를 추가할 수 있게 해주는 도구라고 할 수 있다. Decorate의 "꾸미다"라는 의미에 맞게 기존 function을 꾸며주는 기능을 제공

ds31x.tistory.com

2024.07.24 - [Python] - [Python] Class 간단 정리

 

[Python] Class 간단 정리

OOP 개념https://dsaint31.me/mkdocs_site/python/oop/oop_0_00_OOP/ BME228Object Oriented Programming (OOP) OOP는 Object 에 기반 하여, Object 를 이용 하고 Object 를 만들고(정의 및 구현), Object 를 조합 하여 프로그래밍 하는 P

ds31x.tistory.com