@staticmethod, @classmethod, @property

Leejaegun·2025년 1월 23일

Python & etc

목록 보기
11/27

파이썬을 좀만 더 깊게 파고들어서 깃헙코드를 보면 아주 보기 싫은 @ 문법이 있습니다.
이는 상당히 머리를 아프게 하고 파이썬을 접게 만드는 주요한 원인중에 하나입니다.
여기중에서 좀 괜찮은 것들 3가지 @staticmethod, @classmethod, @property만 알아보도록 하겠습니다.

@staticmethod

@staticmethod는 클래스에 소속된 함수가 아니라, 일반 함수처럼 쓰겠다는 의미입니다.
예시를 들어보겠습니다.

class Person:
	def __init__(self, age):
    	self.age = age
    
    def is_adult_method(self,age): #class에 있는 method는 무조건 self를 처음에 써서 자기자신을 가리키게 되어있습니다. 하지만 앞에 @staticmethod가 붙는다면?
		return age > 20
    
    @staticmethod
    def is_adult(age): #self를 쓰지 않습니다. @staticmethod때문에 첫번째 인자를 일반 함수처럼 받게 됩니다.
    	return age>20
Person.is_adult(25)
-> True

@staticmethod가 유용할 때는, 인스턴스 없이 호출시 직관적이라는 점 말고는 없습니다(그냥 겉멋문법이다 이말입니다)

@classmethod

@classmethod는 자기자신인스턴스가 아니라, 자기자신 클래스에 접근할 때 사용합니다.
이러한 클래스가 있다고 가정하겠습니다.

class Korean:
	country = "korea"
    
    def i_change(self, name):
    	self.country = name
       
       
    @classmethod
    def c_change(self, name):
    	self.country = name

만약

a,b = Korean() , Korean()
print(a.country)
print(b.country)

하면
둘다 , korea가 나오게 됩니다.
그리고 i_change를 하게되면 당연히 옆에 주석처럼 결과가 나오게 됩니다.

a.i_change("south korea")
print(a.country) # south korea
print(b.country) # korea

하지만 @classmethod를 적용한 곳에

a.c_change("south korea")
print(a.country) # south korea
print(b.country) # south korea

로 b에 접근을 하지 않았음에도 불구하고 b 인스턴스에 있는 country 라는 명이 바뀌게 됩니다.

첫번째 인자가 자기 자신의 개개의 인스턴스를 가리키지만,
@classmethod를 붙이게 되면 자기자신의 인스턴스가 아니라, 자기 자신의 소속 클래스를 가리키게 되므로 다 바뀝니다.
그래서 첫번째 인자에 접근해서 뭔가를 건드리면 다른 인스턴스에도 영향을 끼치게 됩니다.
보통 @classmethod는 의미가 다르기 때문에

@classmethod
def set_defaults(cls,prefix,...):
	...

처럼 self로 쓰지 않고 cls로 씁니다.

@property

@property는 함수이지만 변수처럼 사용하고 싶을 때 사용합니다.

class XY:
	def __init__(self, x,y):
   	self._x = x
       self._y =y
    
   @property
   def x(self):
   	print("p")
       return self._x
      

이렇게 한다면
뒤에

c = XY(3,4)
print(c.x) # p \n 3

변수애 접근하듯이 썻지만 괄호를 붙이지 않고 함수가 실행됩니다.
print가 출력되고 3이 출력됨을 볼 수 있습니다.

왜 몇줄씩 추가하면서 굳이 저렇게 할까요?
-> 클래스 밖에서 x값을 바꾸지 못하게 할 때 사용할 수 있습니다.
즉, class의 private 역할을 하고 있다고 생각하면 됩니다.

자세한 내용은 property <- 여기서 참고하면 좋을 것입니다.

profile
Lee_AA

0개의 댓글