대학원 공부/programming language

Instance method vs Classmethod vs Staticmethod

월곡동로봇팔 2020. 10. 8. 19:38

하 이 친구... 진짜 이해하기 개 힘들었다. 근데 직접 내가 사용해보니까 이제 좀 알 것 같다.

 

일딘 method에 대해서 정의를 하고 가면 좋을 것 같다.

 

Instance Method

class Calc:
    
    def add(self, a ,b):
        return a + b

cal = Calc()
cal.add(1,2)  # return 3

method란 class안에 속해 있는 function으로 생각하면 된다. 

 

method는 self라고 정의를 해줘야 클래스에서 객체를 생성하고, 객체가 이 method를 사용할 수 있다. self는 생성된 객체를 의미한다.

 

이 부분은 과감하게 생략하고 넘어간다. 만약 이 부분이 이해가 가지 않는다면, class에 대해서 좀 더 공부를 하고 오는 것이 좋다!!


@classmethod

class Calc:
    
    @classmethod
    def add(a ,b):
        return a + b

cal = Calc()
cal.add(1,2)  # return 3

classmethod는 instance나 class를 인자로 받지 않는다. 따라서 class를 바로 호출해서 method를 호출할 수 있다.

클래스 메서드는 이렇게 전달받은 cls 파라미터를 통해 클래스 변수 등을 엑세스할 수 있다.

instance method와는 거의 비슷하다. 하지만 상속에 관점에서 보면 완전히 다르다. 그 이유는 밑에서 설명하겠다.


@staticmethod

class Calc:
    
    @staticmethod
    def add(a ,b):
        return a + b

cal = Calc()
cal.add(1,2)  # return 3

staticmethod는 직역하면 정적메소드를 의미한다. staticmethod는 instance나 class를 인자로 받지 않는다. self 파라미터를 갖지 않고 인스턴스 변수에 엑세스할 수 없다.

정적 메서드는 보통 객체 필드와 독립적이지만 로직상 클래스내에 포함되는 메서드에 사용된다.

 

규칙이 엄격한 기본 C++이나 java에서는 class 안에서 staticemethod로 구현을 해놓는다면, 객체는 이 staticmethod 를 접근할 수 없다. 하지만 python에서는 접근이 된다....(음... 좀 쓰레기 같다...)

이게 어떤 효과를 불러일으키는지 예시를 들며 설명하면 정말 좋을 것 같아 적어본다.

게임에서 운영자는 여러개의 class를 구현할 것이다. 장착아이템 class, 능력치 class, 캐릭터 class 등등 여러가지 class가 있고, 거기에 구현된 모든 method를 운영자는 쓸 수 있을 것이다.

하지만 이용자가 운영자의 모든 method 를 접근이 가능하다면, 게임 세계 안에서는 크나 큰 혼란이 생길 것이다. 장착아이템 수를 엄청나게 늘릴 수도 있고, 능력치를 9999로 max로 바꿀 수도 있고, 캐릭터 이름을 규칙에 어긋나게 수정할 수도 있을 것이다.

다시 코딩의 세계로 돌아와서, 만약 내가 생성된 객체 안에서는 특정 method를 접근하지 못하게 막는다면, 내가 실수로 그 method를 불러와서 구현을 하더라도, 에러가 발생하게 될 것이다. 현재의 내가 미래의 나의 실수를 막아준 것이다.


@classmethod vs @staticmethod

# coding: utf-8
class Date :

  word = 'date : '

  def __init__(self, date):
  	self.date = self.word + date

  @staticmethod
  def now():
  	return Date("today")


  def show(self):
  	print self.date


>>> a = Date("2016, 9, 13")
>>> a.show()
date : 2016, 9, 13

>>> b = Date.now()
>>> b.show()
date : today



class KoreanDate(Date):
	word = '날짜 : '


>>> a = KoreanDate.now()
>>> a.show()
date : today

출처: https://hamait.tistory.com/635 [HAMA 블로그]

staticmethod의 경우는 now method를 보면, class 인자를 받지 않아서 KoreanDate가 Date 를 상속받아서 사용해도, now method는 Date의 객체를 return하게 되어서 그대로 출력 결과가 동일하다.

# coding: utf-8
class Date :

  word = 'date : '

  def __init__(self, date):
      self.date = self.word + date

  @classmethod
  def now(cls):
      return cls("today")

  def show(self):
      print self.date



class KoreanDate(Date):
	word = '날짜 : '


>>> KoreanDate.now()
>>> a.show() 
날짜 : today

출처: https://hamait.tistory.com/635 [HAMA 블로그]

classmethod의 경우는 now method가 class인자를 뜻하는 cls를 받게 되고, 그 cls를 return하게 된다. 그렇기 때문에 KoreanDate가 Date 를 상속받아서 now method를 쓰게 되면, now는 상속된 class에 귀속되어서 속성까지 쓸 수 있다.

class Person:
    default= "아빠"
    
     def __init__(self):
        self.data = self.default
    
    @classmethod
    def class_person(cls):
        return cls()
    
    @staticmethod
    def static_person():
        return Person()
    
class WhatPerson(Person):
    default = "엄마"
person1 = WhatPerson.class_person()    # return 엄마
person2 = WhatPerson.static_person()   # return 아빠

이 code도 위에 말과 동일하다. staticmethod는 정적이니까 부모클래스의 속성을 그대로 사용하고, classmethod는 부모클래스에서 자식클래스로 넘어간다면, 속성을 이어받아서 자식 클래스의 속성을 method가 접근해서 쓴다. classmethod는 자식 class에 귀속되어 쓰인다고 보면 된다.

 

정리

인스턴스 데이타를 엑세스 할 필요가 없는 경우 클래스 메서드나 정적 메서드를 사용하는데, 이때 보통 클래스 변수를 엑세스할 필요가 있을 때는 classmethod를, 이를 엑세스할 필요가 없을 때는 staticmethod를 사용한다.

 

출처:

medium.com/@hckcksrl/python-%EC%A0%95%EC%A0%81%EB%A9%94%EC%86%8C%EB%93%9C-staticmethod-%EC%99%80-classmethod-6721b0977372

 

Python 정적메소드(@staticmethod 와 @classmethod)

정적메소드

medium.com

frenchkebab.tistory.com/56

 

파이썬 class - @classmethod는 무엇인가?

django 코드를 읽다보면 @classmethod라고 되어 있는 데코레이터를 자주 볼 수 있는데 계속 무시하고 넘어가다가 이번에 검색을 통해서 정리하게 되었다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Cs:..

frenchkebab.tistory.com