여러가지 메서드

  • 인스턴스 메서드 (instance method)
  • 클래스 메서드 (class method)
  • 정적 메서드 (static method)
  • 매직 메서드 (magic method)

인스턴스 메서드

인스턴스 메서드는 인스턴스 속성에 접근할 수 있는 메서드로, 항상 첫번째 파라미터로 self를 가진다. 인스턴스는 즉각적인 이라는 의미이고 컴퓨터에서는 실체라는 뜻을 가지고 있다. 즉, 메모리 상에 객체가 실제로 존재한다 하는 뜻이다.

class Unit:
    def __init__(self, name, hp, shield, damage):
        self.name = name
        self.hp = hp
        self.shield = shield
        self.damage = damage

    def __str__(self):
        return f'[{self.name}] 체력: {self.hp}, 방어막: {self.shield}, 공격력: {self.damage}'

    def hit(self, damage):
        if self.shield >= damage:
            self.shield -= damage
            damage = 0
        else:
            damage -= self.shield
            self.shield = 0

        if damage > 0:
            if self.hp > damage:
                self.hp -= damage
            else:
                self.hp = 0

probe = Unit("프로브", 20, 20, 5)
zealot = Unit("질럿", 100, 60, 16)
dragoon = Unit("드라군", 100, 80, 20)
>>> probe.hit(16)
>>> print(probe)
[프로브] 체력: 20, 방어막: 4, 공격력: 5
>>> probe.hit(16)
>>> print(probe)
[프로브] 체력: 8, 방어막: 0, 공격력: 5

클래스 메서드

클래스 메서드는 클래스 속성에 접근하기 위해 사용하며 클래스를 의미하는 cls를 파라미터로 받는다.
@classmethod 데코레이터로 사용한다.

class Unit:
    count = 0
    def __init__(self, name, hp, shield, damage):
        self.name = name
        self.hp = hp
        self.shield = shield
        self.damage = damage
        Unit.count += 1

    def __str__(self):
        return f'[{self.name}] 체력: {self.hp}, 방어막: {self.shield}, 공격력: {self.damage}'

    @classmethod
    def print_count(cls):
        print(f'생성된 유닛의 수: {cls.count}개')

probe = Unit("프로브", 20, 20, 5)
zealot = Unit("질럿", 100, 60, 16)
dragoon = Unit("드라군", 100, 80, 20)
>>> Unit.print_count()
생성된 유닛의 수: 3개

cls는 현재의 클래스를 의미하고 cls.count는 Unit.count와 동일한 의미이다. 클래스 메서드를 사용할 때는객체를 만들필요 없이 바로 사용이 가능하다.

정적 메서드

정적 메서드는 인스턴스를 만들 필요가 없는 메서드로 self를 받지 않는다. 메서드가 인스턴스 유무와 관계없이 독립적으로 사용될 때 쓴다. @staticmethod를 데코레이터로 사용한다.

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

    @staticmethod
    def sub(x, y):
        return x - y
>>> Math.add(3,4)
7

매직 메서드

매직 메서드는 클래스 안에 정의할 수 있는 스페셜 메서드로 특별한 상황에 호출된다. __이름__의 형태로 되어 있다. __init__() 함수와 __str__() 함수도 매직 메서드에 포함된다.

>>> print(dir(probe))
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'count', 'damage', 'hp', 'name', 'print_count', 'shield']

dir를 통해 기본으로 제공되는 매직 메서드를 살펴볼 수 있다.

str()

__str__()은 객체를 출력할 때 호출되는 메서드이다. 다시말해 객체를 사용자가 이해할 수 있는 문자열로 반환하는 내장 함수로 __str__() 함수를 오버라이딩해서 사용할 수 있다.

__str__()을 본적이 없더라도 str() 함수는 써봤을 것이다. 사실 str()은 내장 함수가 아니라 파이썬 기본 내장 클래스이다. 예를 들어 str(3)을 실행하는 것은 str 내장 함수를 실행하는 것이 아니라 내장 str 클래스의 생성자 메소드를 실행하고 그 인자로 3을 주는 것이다.

이처럼 파이썬에는 자료형에 대한 연산을 정의하는 메소드들이 있다. 그 메소드들은 메소드의 이름 앞위에 __를 쓰고 있다. 또 하나 예를 들어보면 다음과 같다.

>>> 3 + 5
8
>>> (3).__add__(5)
8
>>> 

3 + 5 는 내부적으로 (3).__add__(5)를 수행한다. int 클래스에서는 ‘+’ 연산을 처리하는 __add__메소드를 정의하고 있고, ‘+’ 기호가 들어왔을 때 이 메소드가 실행되는 구조인 것이다. 다시 말해 어떤 값에 대해 +, -, *=, » 등의 연산자를 취하는 것은 내부적으로 __add__, __sub__, __imul__, __rshift__ 메소드를 실행하는 것과 동일하다.

class Monster:
    def __init__(self, health, attack, speed):
        self.health = health
        self.attack = attack
        self.speed = speed

    def __str__(self):
        return f'체력: {self.health}, 공격력: {self.attack}, 속도: {self.speed}'

goblin = Monster(800, 120, 300)
goblin.decreae_health(100)
goblin.get_health()

wolf = Monster(400, 250, 150)
print(wolf)

결과
>>> print(wolf)
체력: 400, 공격력: 250, 속도: 150

객체를 생성하고 print(객체)로 객체 자체를 print 해보면, 자동으로 __str__() 메서드가 호출되어 f’체력: {self.health}, 공격력: {self.attack}, 속도: {self.speed}’메세지를 반환해준다.