Code about AI/Python

파이썬의 클래스(Class)에 대하여

도비(Doby) 2022. 12. 8. 22:17

객체지향 프로그래밍을 공부하기 위함이기보다는 프로젝트를 하는 데에 있어서 여러 패키지의 모듈들을 사용할 일이 많았습니다. 그러다 보니 코드의 구조를 파악하는 데에 있어서 어려움을 겪었고, 근본적인 어려움부터 해결해보려 합니다.


클래스(Class)란?

클래스란 이제까지 써온 구조체처럼 어떤 타입을 사용자의 입맛에 맞게 선언하는 것과 비슷합니다. 그리고, 그러한 클래스로부터 만든 변수를 Object 혹은 Instance라고 합니다. 간단한 예로 학교의 학생들을 가지고 클래스를 만들어 볼 수 있습니다.

 

학교에는 무수히 많은 학생들이 존재하며 각각 학생들은 서로의 성적, 성격 등 많은 것들이 다릅니다. 이러한 특징을 가지고 학생(Student) 클래스를 만들어봅시다. 클래스는 새로운 타입을 선언하는 것과 비슷하다고 했으니 이를 기억하고 만들어봅시다.

class Student:
    def __init__(self, score = 50, personality = 'lazy'): # constructor
        self.score = score
        self.personality = personality
        
    def print_score(self):
        return self.score

 

1) __init__

제일 먼저 __init__이라는 function이 눈에 들어옵니다. __init__은 생성자(Constructor)라고 불리기도 합니다. 클래스로부터 어떤 오브젝트를 만든다고 할 때, 그 변수의 정보들을 초기화하기 위해 오브젝트의 선언과 동시에 호출되는 함수입니다. 클래스를 만들 때, 거의 무조건 쓰인다고 보는 함수이므로 기억해둡시다.

 

2) self

그다음 눈에 들어오는 게 모든 함수에 들어있는 self라는 인자입니다. self에 대해 설명하자면 모든 함수에 대해 필요하다고 생각하면 됩니다. 왜냐하면 여러 개의 오브젝트를 만들게 되면, 이 오브젝트들이 다 같은 함수를 쓰게 됩니다. 그래서 오브젝트 서로를 구별하기 위해 모든 함수에 첫 인자로 넘겨주게 됩니다.

 

3) Method

클래스 내부에 선언된 함수를 메서드라고 합니다. 메서드에도 위에서 말한 것과 마찬가지로 self라는 인자를 넘겨주어 오브젝트를 구분할 수 있게 해주어야 합니다. print_score가 메서드의 예라고 볼 수 있겠네요.

 

+클래스를 왜 사용하는가?

당장의 학생들을 생각해봐도 이유를 알 수 있습니다. 클래스 없이 여러 학생들 변수를 만든다고 했을 때, 10명의 학생들을 만든다고 칩시다. 그러면 성적과 성격까지 하여 총 20개의 변수를 만들어주어야 합니다. List를 사용해서라도 만들 수 있지만 성적과 성격의 변화를 나타내는 함수들까지 만들어주어야 하고, 성적과 성격의 관계에 대해서도 함수를 만들 수 있습니다. 이러한 복합적인 과정을 클래스 안에서 간편하게 처리할 수 있고, 클래스로부터 10명의 오브젝트를 선언하여 쉽게 프로그래밍을 할 수 있기 때문입니다.

 

그럼 Student 클래스를 통해 오브젝트를 선언해봅시다.

James = Student()
Tom = Student(60, 'freak')

James, Tom을 선언했는데 같은 오브젝트이지만 James에는 인자가 없지만, Tom에는 인자가 있습니다. 같은 클래스를 사용하는데 인자가 없어서 오류가 나야 할 것 같은데 나지 않습니다. 이러한 이유는 클래스와 관련된 건 아닙니다. 이유는 파라미터의 Default값이 설정되어있기 때문입니다.

class Student:
    def __init__(self, score, personality): # constructor
        self.score = score
        self.personality = personality
        
    def print_score(self):
        return self.score

위와 같은 클래스 선언이면 James와 같은 오브젝트 선언을 했을 때 오류가 날 것입니다.

TypeError: __init__() missing 2 required positional arguments: 'score' and 'personality'

 

추가적으로 클래스의 여러 생성자 기법(?) 생성하는 방법이 코드마다 다르기 때문에 어려움을 겪을 수 있습니다. 여러 케이스를 통해 코드를 보는 시각을 가져봅시다.

 

Object 선언을 할 때, 인자를 넘길 필요가 없는 경우 (1)

선언 후에 수정은 가능하지만, 굳이 그럴 필요가 있을 만큼 좋은 방법은 아닌 거 같습니다.

class Student:
    def __init__(self): # constructor
        self.score = 50
        self.personality = 'lazy'
        
    def print_score(self):
        return self.score

Object 선언을 할 때, 인자를 넘길 필요가 없는 경우 (2)

위의 결론과 같은데 멤버 변수로 선언하는 건 추후에 다른 용도로 쓸 법한 것 같습니다. 이 또한 좋은 방법은 아닌 거 같습니다.

class Student:
    score = 50
    personality = 'lazy'
        
    def print_score(self):
        return self.score

일반적인 Class

일반적인 방법이지만 값에 대한 Default값들을 위의 Student Class처럼 넣어주면 좋을 거 같습니다.

class Student:
    def __init__(self, score, personality):
        self.score = score
        self.personality = personality
        
    def print_score(self):
        return self.score

 

여러 생성자 기법(?)을 다루다 보니 오해할 수 있는 부분이 있습니다. 꼭 인자로 넘긴 것만 생성자로 이용할 수 없는 것은 아닙니다. 코드로 말하자면 이런 것도 가능하단 말을 하고 싶습니다.

class Student:
    def __init__(self, score = 50, personality = 'lazy'):
        self.score = score
        self.personality = personality
        self.age = 16
        self.number = []
        
    def print_score(self):
        return self.score

Reference