오히려 좋아..

상황이 나쁘게만 흘러가는 것 같을 때 외쳐보자.. .

궁금한 마음으로 포트폴리오 보기

Language/Python

[Python] 정적 메소드 staticmethod, classmethod

junha6316 2021. 3. 27. 11:59

파이썬 클래스의 코드들을 보면 종종 메서드 위에 데코레이터로 다음과 같은 것들이 붙어있을 때가 있다.

 

@staticmethod

@classmethod

 

오늘은 파이썬의 정적 메서드를 만드는 방법인 staticmethod, classmethod에 대해서 알아보도록 하자

본격적인 글에 앞서서 정적메서드(static method)란 무엇일까?

정적 메서드는 클래스가 생성되지 않아도 즉 인스턴스 없이도 사용할 수 있는 함수로 인스턴스에서는 호출 할 수 없는 함수를 가리킨다.

 

1. staticmethod

staticmethod는 메서드를 정적 메소드로 바꿔주는 것으로 데코레이터를 이용해 바꿔준다.

일반적으로 메서드에는 맨 앞의 argument로 self를 넣어주지만 staticmethod에는 넣어주지 않는다.

class Calculation:
	
    @staticmethod
    def add(x,y):
    	return x + y

Calculation.add(1,3)

     

하지만 위에서 정의 했다시피 정적 메서드는  인스턴스에서는 접근하지 못해야하지만 아래처럼 가능하다.

원래 자바나  C++에서는 에러가 발생하지만 파이썬에서는 사용가능하다. 유연해서 장점으로 볼 수도 있지만 유연하게 작성한 코드가 발생시키는 복잡성 관점에서 볼 때는 단점으로 볼 수 있을 거 같다.

class Calculation:
	
    @staticmethod
    def add(x,y):
    	return x + y

calc = Calculation()
calc.add(1,3)

 

2. classmethod

classmethod 역시 메서드를 정적 메서드화 시켜준다. staticmethod와 동일하게 데코레이터 형태로 사용하며 static 메서드와의 차이는 맨 앞의 인자로 클래스 자기자신 cls를 넣어 주어야한다. 한편 classmethod 역시 유연하게 사용가능하다.

class Calculation:
	
    @classmethod
    def add(cls,x,y):
    	return x + y

Calculation.add(1,1)

 

 

3. @staticmethod @classmethod 차이

위의 설명에서 staticmethod와 classmethod의 차이가 함수의 첫번째 인자로 cls가 들어간다는 것이였다.

설명만 들으면 이런 생각이 든다. 어쩌라는거지.. 

이러한 특징은 클래스를 상속해서 사용할 때 유용하게 사용되는데 가령 Dog 클래스를 예를 들어 이야기 해보자

class Dog:
    
    default_country = "한국"
    
    def __init__(self):
    	self.bark = self.default_country + "개는 왈왈"
        
    @classmethod
    def cls_country(cls):
    	return cls()
    
    @staticmethod
    def stat_country():
    	return Dog()
     
    def make_sound(self):
    	print(self.bark)
        
class EnglishDog(Dog):
 	default_country = "영국"
    

EnglishDog에서 아래 코드를 실행 시켜보면 

stat = EnglishDog.stat_country()
cls = EnglishDog.cls_country()

stat.make_sound()
cls.make_sound()

결과는 아래와 같다

월월

즉 staticclass에서는 Dog() 클래스의 default_country를 사용하지만 classmethod는 cls를 이용해 상속된 class EnglishDog에 접근하는 것을 알 수 있다.

 

4. 실제 사용 예

파이썬 웹 프레임워크인 장고의 예시를 들고왔다. 장고에서는 model이라는 클래스을 이용해 데이터베이스를 조작하는데 아래와 같이 정의 하면 일련의 과정을 거쳐 데이터베이스에 테이블을 생성한다.

class Item(models.Model):

	""" 아이템 모델 정의 """

    name = models.CharField(max_length=40)
    damage = models.IntergerField()
    tier = models.CharField(max_length=20)
    cash = models.IntergerField()
    description = models.CharField()

 

이 모델에서 클래스 메서드는 다음과 같이 사용할 수 있다.

class Item(models.Model):

	""" 아이템 모델 정의 """

    name = models.CharField(max_length=40)
    damage = models.IntergerField()
    tier = models.CharField(max_length=20)
    cash = models.IntergerField()
    description = models.CharField()
    
    @classmethod
    def get_rare_items(cls) -> QuerySet:
        return Item.objects.filter(tier="RARE")
rare_items = Item.get_rare_items()

 

즉 자주 사용하는 쿼리셋을 클래스 메서드로 구현해서 사용할 수 있다. 물론 비즈니스 로직이 복잡해지면 클래스가 너무 커지기 때문에 manager로 빼서 따로 관리하는 것도 좋은 방법이다. 아래 글은 manager와 클래스 메서드 사이의 찬반의견을 정리해놓은 글이다.

참고 하길 바란다

https://www.b-list.org/weblog/2008/feb/25/managers/

 

Managers versus class methods

Managers versus class methods