[Python] Instance, Class, and Static Methods

olxtar·2022년 4월 4일
0
post-thumbnail

참고 : https://realpython.com/instance-class-and-static-methods-demystified/

참고 : https://zzsza.github.io/development/2020/07/05/python-class/

니가쓴거 : [Python] 객체지향-1 , [Python] 객체지향-2

간단복습 :

  • class : 직업 =축구선수
  • instance : 실체 =(실제)축구선수
  • object : 객체 =손흥민, 박지성 등
  • method : 기능(?) =슈팅, 패싱, 헤딩 등
  • attribute : 속성(?) =신장, 득점수, 어시수 등



0. Overview

class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'


0-1. Instance Methods

def method(self):
	return 'instance method called', self

instance method는 self parameter를 통해
해당 object(객체 즉, 다른 instance들)의 attributes or other method에 접근 가능하다.
해당 class로 만들어진 다른 instance에 접근 가능하다는 것인가?


또한 self.__class__ attribute를 통해 class 자체에도 접근 가능하다.

  • 인스턴스에 따라서 다르게 동작해야함
  • 인스턴스를 통해서만 호출 가능
  • 첫번째 인자(argument)로 self 전달하며, 인스턴스 자신을 전달




0-2. Class Methods

@classmethod
def classmethod(cls):
    return 'class method called', cls

self parameter를 받지 않고 Class를 의미하는 cls parameter를 받음

따라서 object는 수정할 수 없다. 오로지 class 자체만 수정 가능

  • 클래스에 직접 접근
  • @classmethod 라는 데코레이터로 정의
  • 첫번째 인자(argument)로 cls를 전달하며, 클래스 자신을 전달




0-3. Static Mehtods

@staticmethod
def staticmethod():
	return 'static method called'

Static method takes neither self or cls parameter 즉, selfcls parameter를 받지 않는다.

따라서 object, class를 수정할 수 없다.






1. See Them In Action!

class MyClass:
    def method(self):
        return 'instance method called', self

    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    @staticmethod
    def staticmethod():
        return 'static method called'
obj = MyClass()

자 이제 하나의 Class에 세가지 메소드 (인스턴스 메소드, 클래스 메소드, 정적 메소드)를 만들어서 어떻게 작동되는지 확인해보자.
[+] obj이라는 변수에 MyClass()를 할당함 즉, obj이라는 instance를 생성함!

먼저 3개의 메소드 모두 호출 시 호출되었다는 문구를 return 한다. '--- method called'
그리고 정적 메소드를 제외한 두 개의 메소드는 selfcls를 return함.





print(obj.method())
print(obj.classmethod())
print(obj.staticmethod())

>>>
('instance method called', <__main__.MyClass object at 0x000001988867C370>)
('class method called', <class '__main__.MyClass'>)
static method called

MyClass라는 클래스로 obj를 생성하였고
해당 obj으로 각각의 메소드를 호출하였다.

여기서 Keypoint는 인스턴스 메소드와 클래스 메소드는 argument로 무언가를 넘겨주지 않아도 자동으로
<__main__.MyClass object at 0x000001988867C370>
<class '__main__.MyClass'>를 각각 전달받았다는 것이다.





1-1. Class-method in Action

자... 김치를 만드는 Class가 있다.
이 김치 클래스는 생성 시 재료, 즉 ingredient argument를 받는다.
재료가 오이일 경우 오이소박이
재료가 무일 경우 깍두기
재료가 배추일 경우 배추김치가 된다.

class Kimchi():
    name = '김치'
    
    # instance method
    def __init__(self, ingredient):
        
        if ingredient == 'Cucumber':
            self.name = '오이소박이'
            
        elif ingredient == 'Radish':
            self.name = '깍두기'
            
        elif ingredient == 'Cabbage':
            self.name = '배추김치'
        
        else:
            pass
            
        print(f'나는 {self.name}!!')

        
    @classmethod
    def whatru(cls):
        print(cls.name)

김치를 만드는 클래스를 만들었으니
진짜 김치를 만들어보자!



Kimchi_1 = Kimchi('Cucumber')
Kimchi_2 = Kimchi('Radish')

>>>
나는 오이소박이!!
나는 깍두기!!

위 코드에서 Kimchi_1과 Kimchi_2는 Kimchi라는 클래스로 만들어진 인스턴스이다.
인스턴스 메소드를 보면 (self, ingredient)를 넘긴다. 즉, self인스턴스 자기 자신이므로

  • Kimchi_1 case
    __init__ method에 (Kimchi_1, 'Cucumber')을 argument로 넘김
    \therefore self.name = Kimchi_1.name = '오이소박이'

  • Kimchi_2 case
    __init__ method에 (Kimchi_2, 'Radish')을 argument로 넘김
    \therefore self.name = Kimchi_2.name = '깍두기`


이와 같이 인스턴스 메소드는 self parameter를 통해 인스턴스에 접근 가능하다.

이와 다르게 클래스에 접근하고 싶으면 어떻게 할까? \rightarrow 클래스 메소드



Kimchi_1.whatru()

>>
김치

앞선 코드에서 Kimchi_1은 Kimchi라는 클래스로 만들어진 인스턴스이다.
클래스 메소드를 보면 (cls)를 넘긴다. 즉 cls클래스이므로

  • Kimchi_1 case
    whatru method에 (Kimchi)를 argument로 넘김
    \therefore cls.name = Kimchi.name = '김치'

[+] Kimchi_1의 name은 그대로임을 확인

Kimchi_1.name

>>
'오이소박이'




1-2. Static-method in Action

class Pizza:
	def __init__(self, radius, ingredients):
    	self.radius = radius
        self.ingredients = ingredients
        
        
    def area(self):
    	return self.circle_area(self.radius)
        
    @staticmethod
    def circle_area(r):
    	return r ** 2 * math.pi
        
p = Pizza(4, ['mozzarella', 'pepperoni'])

(instance, radius, ingredients)를 받아서 Pizza를 만드는 클래스를 만들었다. method는 두개가 있는데...

  • 인스턴스 메소드 : area
  • 정적 메소드 : circle_area

인스턴스 메소드를 보면 자기자신 인스턴스의 circle_area method를 호출해서, 자기자신의 radius를 argument로 전달하고 있다.

정적 메소드를 보면 뜬금없는 r을 argument로 전달하고 πr2\pi r^2 을 반환한다.

p.area()

>>>
50.26548245743669
Pizza.circle_area(4)

>>>
50.26548245743669

실행결과는 위와 같다.

@staticmethod인 circle_area 메소드는 Class와는 아무 상관없는 r이라는 argument를 받는다. 따라서 이 메소드는 인스턴스에서도 사용가능하고 대신 인스턴스, 즉 자기자신 self.radius값이 있어야함 클래스 자체에서 사용 가능하다 대신 self.radius값이 없으므로 임의로 값을 넘겨줘야함

profile
예술과 기술

0개의 댓글