-
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 를 적용한 부분을 다른 포스팅에 기록할 예정이다.
'Backend > Python' 카테고리의 다른 글
[병렬 처리] python multithreading 도입기 (feat.multiprocess 차이) (1) 2024.02.23 Python batch 파일 윈도우 스케줄러에 등록하기 (0) 2024.01.16 Pyinstaller를 사용해서 python 실행 파일 만들고, window 서비스에 등록하기 (0) 2024.01.15 파이썬 SMTP이용하여 email 보내기 (0) 2024.01.15