ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python에서 @staticmethod, @classmethod, instance method,개념 정리
    Backend/Python 2024. 2. 16. 11:32

    필자는 다른 프로젝트에서 @classmethod를 사용하는 것을 보았다. 

     

    python에서는 자주 사용하지 않았는데, 이번 기회에 개념을 정리하고 SQLALchemy에 적용하기 위해 알아보았다.

     

    먼저, method에는 크게, instance method, static method, class method가 있는데, 

    그 중 가장 많이 쓰이는 instance method는 사실 우리가 가장 많이 사용하고 있었다.

     

    먼저, Shape() 라는 클래스를 하나 만들었고, 클래스 변수를 선언했다.

    -> 클래스 변수는 내외적으로 호출(Shape.cnt) 할 수 있다!

     

    class Shape():
        # 클래스 변수
        cnt = 0
        
        def __init__(self,width,height):
            self.width = width
            self.height = height
            Shape.cnt += 1
        
        # 인스턴스 method
        def calculArea(self):
            area = self.width * self.height
            print(area, "area")
            return area

     

    여기서 instance method는 calculArea인데 -> 인스턴스 변수에 접근 위해 -> 항상 첫번째 파라미터에 "self" 기입

     

    (※ self 즉, 객체 자신을 의미함)

     

    [인스턴스 변수]

    1. 인스턴스 변수 == "self.변수명"  가 존재 

    하나의 클래스로 여러개 객체 찍어내기 가능 ( 붕어빵 틀 <-> 붕어빵 처럼)

     

    2. 각 객체별로 서로 다른 값을 가지는 변수

     

    3. 내부에서는 "self.* "를 이용해서 접근, 외부 = 객체변수.인스턴스변수 로 접근

     

    4. 만약 private 하게 사용하고 싶다면 변수명 앞에 밑줄 두개(__)를 붙여준다. (함수도 마찬가지)

     

     

    [초기화]

    우리가 흔히  class를 생성하면, 아래에 바로 __init__()을 붙이는데, 클래스 intializer 라고 명명한다.

    초기생성자는 객체를 만들때, 인스턴스 변수를 초기화 하거나, 객체 자체를 초기화 하기 위해 사용한다.

     

    @staticmethod  vs  @classmethod

     

    [static method 특징]

     

    1. static method는 self 파라미터를 가지지 않는다.

     

    2. self를 가지지 않기에, 인스턴스 변수에 접근 불가

     

    3. 보통적으로 독립적일때 사용 (클래스 변수 접근 하지 않을때) -> 유틸리티성 이며, 어떤 변화를 일으키지 않고 항상 같은 값 출력을 위해 사용 

     

    class Shape():
        cnt = 0
        
        def __init__(self,width,height):
            self.width = width
            self.height = height
            Shape.cnt += 1
        
        # 인스턴스 method
        def calculArea(self):
            area = self.width * self.height
            print(area, "area")
            return area 
        
        # static method
        @staticmethod
        def square(leftwidth, rightwidth):
            return leftwidth == rightwidth
    
    
    a = Shape(2,4)
    b = Shape(3,7)
    c = Shape(200,2)
    
    print("====== a,b,c, 객체 생성 및 함수 적용 ======")
    
    a.calculArea()
    b.calculArea()
    c.calculArea()
    
    print("====== a,b,c 기존에 각각 객체가 있는데 staticmethod 적용할 때 ======")
    
    print(a.square(1,1))
    print(b.square(2,1))
    print(c.square(3,1))
    
    print("====== 객체 생성하지 않고 바로 staticmethod 적용했을 때 ====== ")
    
    print(Shape.square(3,1))
    print(Shape.square(2,2))
    print(Shape.square(3,1))

    위와 같이 코드를 실행 했을 때, 객체 생성 유무에 따라서 테스트도 함께 해보았다.

    그 결과는 아래와 같이 볼 수 있다. 

     

     

    기존 a ,b ,c 객체를 생성해서 이미 값을 넣었지만,  square()함수에 넣은 매개변수에 따른 결과를 나타냄을 볼 수 있고, 객체 없이 클래스.함수로 호출해서 다시 다른 값을 넣었지만 이에 따른 결과 값이 도출되는 것을 볼 수 있다.

    즉, 독립적으로 함수가 실행된다는 것을 알 수 있다.

     

     

    [class method 특징]

     

    1. static method와 비슷하지만, self 대신 cls를 사용한다.

     

    2. cls를 통해서 클래스 변수에 접근 가능 (클래스 속성에 접근 할 때 자주 사용

     

    아래의 클래스를 보면 이해가 될 것 이다. 

     

    class Shape():
        cnt = 0
        
        def __init__(self,width,height):
            self.width = width
            self.height = height
            Shape.cnt += 1
        
        # 인스턴스 method
        def calculArea(self):
            area = self.width * self.height
            print(area, "area")
            return area 
        
        @classmethod
        def chg_cnt(cls, cnt):
            cls.cnt = cnt
            print(cnt, "cnt")
            
        @classmethod
        def calculCnt(cls, cnt2):
            print(cls.cnt, "cnt1")
            print(cls.cnt * cnt2, "result")
            return cls.cnt * cnt2
    
    
    a = Shape(2,4)
    b = Shape(3,7)
    
    print("====== 객체 생성 후 classmethod 적용했을 때 ====== ")
    
    a.chg_cnt(3)
    b.chg_cnt(4)
    
    print("====== 객체 없이 classmethod 적용했을 때 ====== ")
    
    Shape.calculCnt(3)
    Shape.calculCnt(4)
    Shape.calculCnt(5)

     

    여기도 마찬가지로 객체의 유무에 따라서 테스트 해보았다.

     

     

    객체 없이 classmethod를 적용했을 때를 보면, 마지막으로 클래스 매서드인 chg_cnt 의 cnt  값을 상속받아서 결과 값이 보이는 것을 알 수 있다. 

     

    이번에, 각각의 method를 정리하면서 헷갈리지 않고, 개념을 정립할 수 있어서 좋았다. 이를 바탕으로 SQLAlchemy에서 classmethod 를 적용한 부분을 다른 포스팅에 기록할 예정이다.

Designed by Tistory.