클래스에 대해서
세계에서 가장 자주 쓰이는 언어 중 하나인 C언어에는 클래스라는 개념이 존재하지 않는다. 그말인즉슨, 클래스를 사용하지 않고도 원하는 기능을 구현하는데에는 지장이 없다는 것이다.
그럼에도 우리가 클래스를 배우고 사용하는 것은 클래스를 알고, 사용함으로써 얻을 수 있는 이점이 많기 때문이다.
우리는 여지껏 파이선을 공부하면서 int, float 등의 많은 데이터 타입을 배워 왔다.
우리가 다루게 될 클래스는 쉽게 말해서, "사용자 지정 데이터 타입" 이다.
클래스를 만드는 법
클래스는 class name: 으로 만들 수 있다.
class는 클래스를 생성하기 위한 예약어이며, name에는 개발자가 원하는 어떤 이름이라도 넣을 수 있다. 하지만 코드를 읽는 사람으로 하여금 이해를 쉽게 하기 위하여 이 클래스가 주로 어떤 정보를 저장하기 위한 "데이터 타입" 인지 명시하는 것이 좋다.
사람의 인적사항을 담기 위한 새로운 '데이터 타입', Person을 만들어 보자.
class Person:
pass
#pass는 함수, 클래스 등을 만들 때 일단 껍데기만을 만들어 놓고 내부를 구현하고 싶지 않을때,
#Syntax 에러를 피하기 위해 사용된다.
john = Person()
이로써 새로운 클래스인 Person이 만들어졌다. 그리고 John이라는 사람의 정보를 담기 위한 변수 john을 만들었다.
클래스에 의해 해당 클래스의 정보를 담게 된 변수를 '해당 클래스의 인스턴스'라고 부른다. 따라서 john 또한 'Person 클래스의 인스턴스'임을 알 수 있다.
하지만 아직 내부의 어떤 것도 구현하지 않았기 때문에 Person 클래스에는 어떠한 정보도 담길 수 없다.
어떻게 하면 이 클래스가 유효한 데이터 타입으로서 기능하게 할 수 있을까?
메서드(Method)
우리는 여기서 메서드의 필요성을 느끼게 된다.
메서드란, 일종의 클래스 안에 정의된 함수로, 필요에 따라 호출되어 해당 클래스에 관련된 작업을 한다.
class Person:
def set_name(self, new_name):
self.name = new_name
def self_introduce(self):
print("My name is " + self.name)
아까 만들었던 Person 클래스 안에 set_name(), self_introduce()라는 메서드를 구현했다.
두 메서드는 각각 이 클래스의 인스턴스에 이름을 저장하고, 저장된 이름을 바탕으로 자기소개를 하도록 한다. 이는 기존의 빌트인 데이터타입에서는 찾아볼 수 없는, 분명히 독창적인 기능이다.
메서드를 구현할 때에 parameter로서 사용된 self는 호출의 주체가 자기 자신임을 명시하는 일종의 관례이다.
객체의 메서드가 호출될 때, 자동으로 첫 번째 매개변수에는 이 메서드를 호출한 객체인 자기 자신이 자동으로 전달되기 때문에, 이 메서드를 호출한 주체가 자기 자신임을 한번 다시 명시해주는 것이다.
다시 아까 만들었던 Person 클래스와 그 인스턴스 john을 보도록 하자.
class Person:
def set_name(self, new_name):
self.name = new_name
def self_introduce(self):
print("My name is " + self.name)
john = Person()
john.set_name('John')
john.self_introduce()
My name is John
클래스 Person을 만들고, 그 인스턴스인 john을 만들었다.
메서드인 set_name()을 사용하여 john 인스턴스의 name 변수에 'john'을 대입했고,
set_introduce()를 사용하여 john 인스턴스의 정보를 바탕으로 자기소개를 했다.
생성자 __init__
클래스를 통해 객체를 처음 생성할 때에 자동으로 특정 값을 할당하도록 하고 싶으면 어떻게 해야 할까?
이를 위해 존재하는 것이 특수 메서드인 __init__이다.
객체가 생성될 때, 자동으로 __init__ 메서드를 호출하게 된다.
class Person:
def __init__(self):
self.name = "non-existent"
def set_name(self, new_name):
self.name = new_name
def self_introduce(self):
print("My name is " + self.name)
생성자 __init__ 메서드를 통해 객체가 처음 생성될 때, 자기 자신의 이름을 "non-existent"로 설정하도록 했다.
기존에는 객체를 생성한 직후에 self_introduce() 메서드를 호출할 경우엔, 존재하지 않는 값이 필요하기 때문에 NameError가 발생했지만, 생성자를 사용해서 에러가 발생하는 것을 막을 수 있다.