본문 바로가기
Python

[Python] 파이썬 - 02. 클래스 인스턴스, self, __init__ 이란?

by Hoody Coder 2023. 2. 5.

 

우리는 앞에서 아래와같은 계산기 클래스를 통해 간단하게 

클래스가 어떻게 생긴 형태인지 알아보았다.

class Calculator:
    def __init__(self):
        self.result = 0


    def sum(self, num):
        self.result += num
        return self.result

 
cal1 = Calculator()
cal2 = Calculator()

print(cal1.sum(3))
print(cal1.sum(4))
print(cal2.sum(3))
print(cal2.sum(4))

오늘은 이 코드들에 있는 메서드들을 통해서 인스턴스(instance), self, __init__ 에 대해서 알아보자.

 

 

1. 인스턴스(Instance = 객체)

위의 코드 에서 해당 부분에 해당한다

cal1 = Calculator()
cal2 = Calculator()

우리는 이전의 게시글에서 class는 붕어빵틀과 같은 설계도의 역할을 한다고 배웠다.

그렇다면 붕어빵틀은 왜 필요한 것인가? 바로 붕어빵을 만들기 위해서이다.

이 이론(?)에 입각하여 위의 코드를 본다면 class Calculator은 왜 필요할까?

class 안에 있는 함수들을 사용하기 위해서인 것이다.

다시 붕어빵을 만드는 상황으로 돌아가보자. 열심히 붕어빵장수가 붕어빵틀에 열심히 재료들을 섞었다. 잠시 후 완성되는 것은 무었일까? 당연히 붕어빵이다. 붕어빵틀에 재료를 부었으면 붕어빵이 나오는 것은 당연한 것이 아닌가.

클래스가 붕어빵틀이였다면 인스턴스는 붕어빵과 같은 개념이다.

즉 cal1 = Calculator()은 Calculator라는 클래스 (= 붕어빵틀)에서 생성된 인스턴스(= 붕어빵)인 것이다. 이런 인스턴스는 객체라고도 불리며 1개의 클래스가 있다면 ( = 한개의 붕어빵 틀) 여러개의 인스턴스(= 수 많은 붕어빵)을 만들 수 있다. 또한 인스턴스명은 사용자의 편의에 따라 자유롭게 작성할 수 있다.

인스턴스명 = 클래스명()

 

그렇다면 인스턴스를 만드는 이유는 무엇일까? 붕어빵틀에 넣는 재료에 따라 나오는 팥붕, 슈붕이 나오듯

클래스에 넣는 매개인자에따라 다른 결과값을 만들 수 있기 때문이다. 즉 클래스는 어떤 로직에대한 틀을 제공하는 것이지 

모든 클래스가 같은 값을 제공하는 것은 아니라는 것을 기억하자.

 


2. self

위의 코드 2, 5 번째 줄은 아래와 같이 작성되어있었다.

 

def __init__(self):
	pass
    
def sum(self, num):
	pass

함수 안에 인수를 살펴보니 첫번째에 self가 선언되어있다. 이 self는 어떤 역할을 하는 것인가?

잠시 학창시절 배운 영어단어에 대해 생각해보자 myself, yourself, 물은 셀프

무엇이 생각나는가? self는 자신을 의미하는 것을 알 수 있다. 이는 파이썬에서도 마찬가지다 함수에서의 self란 객체의 인스턴스 그 자신을 의미한다.

그 말은 self대신 인스턴스명 자신을 인자로 넣어도 식이 정상동작한다는 것이다. 아직 __init__에 대해 배우지 않았으니 def sum함수를 예로 들어 다음 코드를 작성해보자

 

class Calculator:

    def __init__(self):
        self.result = 0

    def sum(sum, num):
        sum.result += num
        return sum.result
 

cal1 = Calculator()
cal2 = Calculator()

print(cal1.sum(3))
print(cal1.sum(4))
print(cal2.sum(3))
print(cal2.sum(4))

self가 들어가는 위치에 인스턴스 자신인 sum을 대입하였지만 결과는 self와 동일함을 알 수 있다.

사실 파이썬의 모든 인스턴스 메소드(함수)의 첫번째 인자에는 이 self가 포함되어야 하는 점은 파이썬에 대한 비판으로 제기되기도 한다.

 


3. __init__()

마지막으로 알아볼 것은 코드의 2번째 줄에 언급된 __init__() 메소드 이다.

이에 대해 알아보기전 다음과 같은 상황을 가정해보자.

계산기를 만들어 달라는 요청을 받았는데 (굳이) 결과값은 숫자식만 나오는 것 뿐만 아니라 어떤 연산을 했는지 까지 알고 싶다는 것이다. ( 더하기 연산을 했다면 "더하기 공식 1 + 2 = 3 입니다." 라는 결과값이 출력되어야 한다.)

때문에 이를 해결하려던 당신은 일단 setname이라는 메소드(함수)를 통해서 공식명을 받고 더하기 메소드(함수)를 만들어 이를 확인해보려고 한다

이에 대한 코드는 아래와 같다.

class Calculator:

    def setname(self, name):
        self.name = name

    def sum(self, first, second):
        result = first + second
        print("%s 공식 : %s + %s = %s 입니다." % (self.name, first, second, result))

    def sub(self, first, second):
        result = first - second
        print("%s 공식 : %s - %s = %s 입니다." % (self.name, first, second, result))

 
cal1 = Calculator()
cal2 = Calculator()

cal1.setname("더하기")
cal1.sum(2, 3)
cal2.setname("빼기")
cal2.sub(5, 4)

(print()안에 작성된 %s 는 문자열 포맷팅기능으로 이는 추후에 작성하도록 하겠다. 지금은 %s는 문자열 포맷팅을 의미하고, 불러오는 값은 %(self.name, first, second, result)에 저장된 값을 불러온다는 점만 알아두자.)

이에따라 작성된 코드의 결과값은 다음과 같다.

 

성공적으로 요구사항을 마친 당신은 서비스업체가 좋아할 생각에 싱글벙글하며 코드 내용을 보냈다.

그리고 서비스 업체는 당신의 코드를 서비스하기 시작하였다.

몇주 뒤, 서비스 업체는 당신에게 항의를 하였다. 몇몇 고객들이 계산기가 제대로 작동하지 않는다고 불만을 컴플레인을 걸었기 때문이다. 상황을 들어보니 고객은 다음과 같이 서비스를 사용하였다.

 

cal1 = Calculator()
cal2 = Calculator()

cal1.sum(2, 3)
cal2.sub(5, 4)

그 때마다 당신은 고객이 ca1.setneme("더하기") 와 같은 연산수식명을 입력해야 정상작동한다고 말해주었지만, 고객들은 무슨 계산기 한번사용하는데 setname이니 뭐니 그리 복잡한게 많냐면서 불만을 토하고있다. 그래서 당신이 고안한 방법이 바로 __init__()함수를 쓰는 것이다.

__init__()함수는 초기화 생성자 또는 초기화메소드라고 불리는데 인스턴스를 만들때 항상 실행된다는 의미이다.

단 init()함수를 사용할때는 그 사용방식이 조금 달라지는데 인스턴스가 생성될때 함께 변수명을 함께 선언해주어야 한다. 이를 통해 완성된 코드는 다음과 같다.

 

class Calculator:

    def __init__(self, name):
        self.name = name

    def sum(self, first, second):
        result = first + second
        print("%s 공식 : %s + %s = %s 입니다." % (self.name, first, second, result))

    def sub(self, first, second):
        result = first - second
        print("%s 공식 : %s - %s = %s 입니다." % (self.name, first, second, result))

 

cal1 = Calculator("더하기")
cal2 = Calculator("빼기")

cal1.sum(2, 3)
cal2.sub(5, 4)

 

 

Index로 돌아가기