toggle menu

파이썬에서 class와 __init__

2020. 5. 10. 07:17 Python

클래스... 이름만 들어도 뭔가 어려워 보이지 않는가?

 

클래스가 뭐지?

필자가 파이썬을 공부하면서 이해할 수 없었던 점이 한 가지 있었다.

클래스가 도통 이해가 가지 않았다. 이미 함수가 있는데 굳이 클래스를 써야 할까? 

 

필자에게 클래스란 정말 넘을 수 없는 산과 같았다. 도통 객체지향의 개념이 이해가 가지 않았다.

 

하지만 객체지향이란 개념은 처음에만 넘기 힘든 산이였었다. 정말 필자의 코드는 객체지향을 쓰기 전과 후로 나뉜다고 할 정도로 코드가 깔끔해졌다.

 

이번 포스팅에서는 파이썬 객체지향의 꽃인 클래스와 여러 특별 메서드들에 대해서 알아보도록 하겠다.


클래스는 왜 필요할까?

클래스가 뭔지 알아보기에 앞서, 클래스가 왜 필요한지 설명하는 게 먼저일 것 같다. 클래스가 왜 필요한지 알아야, 클래스를 쓸 것 아닌가?

 

클래스는 코드를 짤 때 꼭 필요하지 않다. 그 말은 오로지 함수(def)만 이용해서 프로그램을 짤 수 있다는 뜻이다.

 

함수를 쉽게 설명하자면, 나중에 사용하기 위한 코드를 모아둔 박스 같은 것이다. 하지만 그런 박스가 점점 더 많아진다면, 그 박스들은 어떻게 관리해야 할까?

 

이럴 때 바로 클래스가 필요한 시점이다.

 

클래스는 박스를 관리하는 컨테이너라고 생각하면 쉽다. 아래 예제 코드를 보면서 이해해보자.

 

학생의 GPA(학점)을 구하는 계산기를 클래스를 쓰지 않은 상태로 한번 만들어보자.

 

def calculateGPA(gradeDict):
    return sum(gradeDict.values())/len(gradeDict)

students = {}
name, age, gender, level, grades = "name", "age", "gender", "level", "grades"
john, jane = "john", "jane"
math = "math"
students[john] = {}
students[john][age] = 12
students[john][gender] = "male"
students[john][level] = 6
students[john][grades] = {math:3.3}

students[jane] = {}
students[jane][age] = 12
students[jane][gender] = "female"
students[jane][level] = 6
students[jane][grades] = {math:3.5}

print(calculateGPA(students[john][grades]))
print(calculateGPA(students[jane][grades]))

### 출력값 ###
3.3
3.5

 

코드가 굉장히 길다. 단순히 학생의 GPA를 구하는 것뿐만 아니라, 학생의 다른 기타 정보도 넣었기 때문이다.

 

이 코드에서, 학생을 3명 더 추가해야 한다고 생각해보자. 정말 귀찮은 짓일 것이다.

 

귀찮아..

하지만 클래스를 사용하면 위 고민을 깔끔하게 해결할 수 있다.

 

아래 코드는 지금 이해가 가지 않아도 괜찮다. 나중에 차근차근 알아볼 것이다.

 

class Student(object):
    def __init__(self, name, age, gender, level, grades=None):
        self.name = name
        self.age = age
        self.gender = gender
        self.level = level
        self.grades = grades or {}

    def setGrade(self, course, grade):
        self.grades[course] = grade

    def getGrade(self, course):
        return self.grades[course]

    def getGPA(self):
        return sum(self.grades.values())/len(self.grades)

john = Student("John", 12, "male", 6, {"math":3.3})
jane = Student("Jane", 12, "female", 6, {"math":3.5})

print(john.getGPA())
print(jane.getGPA())

### 출력값 ###
3.3
3.5

 

아까에 비해서 코드가 정말 깔끔해졌다. 여기서 학생을 더 추가하고 싶을 때는 이미 만들어진 클래스를 통해서 편하게 얼마든지 더 만들어줄 수가 있다.

 

클래스는 코드를 재사용 가능하게끔 해준다.


클래스 생성하기

클래스를 왜 써야 하는지 알아봤으니, 이제 클래스를 사용해볼 차례다.

 

클래스를 사용하기 위해서는 클래스를 먼저 생성해야 하는데, 매우 간단하다.

 

class 클래스명:
	함수들...

 

위 코드와 같은 형태로 생성할 수 있다.

 

아래 예제 코드를 한번 살펴보자.

 

class Singer:
    def sing(self):
        print('노래 부르는중...')

eminem = Singer()

eminem.sing()

### 출력값 ###
노래 부르는중...

 

클래스 안에 있는 함수를 메서드라고 한다.

 

Singer라는 클래스가 있고 그 속에 sing이라는 메서드가 있다. 우리는 에미넴이라는 변수를 만들어 그 안에 Singer 클래스를 할당했고, 결과적으로 Singer안에 있는 sing 메서드를 eminem.sing()으로 접근할 수 있게 되었다.


__init__ 생성자 메서드

클래스 안에는 특이한 메서드들이 몇 가지 있다. 그중에 반드시 알아야 할 것이 한 가지 있는데, 그것이 바로 __init__ 메서드다.

 

클래스로 구현해본 계산기를 살펴보자.

 

class Calculator:
    def __init__(self, first_number, second_number):
        self.first_number = first_number
        self.second_number = second_number
        
    def add(self):
        return self.first_number + self.second_number


a = Calculator(1, 2)

print("첫번째 숫자는 " + str(a.first_number))
print("두번째 숫자는 " + str(a.second_number))
print("서로 더한 값은 " + str(a.add()))

### 출력값 ###
첫번째 숫자는 1
두번째 숫자는 2
서로 더한 값은 3

 

Calculator라는 클래스를 생성하면서 1과 2라는 값을 전달해준 걸 볼 수 있다. 그런데, Calculator 클래스에는 인자를 받는 곳이 따로 정해져 있지 않는데 이 값은 어디서 받는 걸까?

 

그 역할을 해주는 것이 바로 __init__ 메서드다.

 

클래스를 생성하면서 1과 2를 Calculator 클래스에게 넘겨준 걸 볼 수 있다. 

 

넘겨진 파라미터는 생성자 메서드인 __init__에서 self를 사용해 변수를 생성해준다. 그래서 다른 함수에서도 self. 변수명을 통해 이 변수에 접근할 수 있다.

 

그리고 또한 클래스 밖에서도 오브젝트명.변수명으로 접근할 수 있다.


정리

클래스는 일종의 붕어빵 틀이다.

(컨테이너) __init__은 생성자 메소드다. 

댓글