클래스
객체를 만들기 위해 사용하는 '틀'
- 파이썬의 클래스 개념은 C++에서의 클래스와 다를게 없다. 따라서 클래스 개념은 다음 게시글을 참고하자.
클래스 정의
- 클래스는 class 키워드를 이용하여 생성한다.
class 클래스명:
실행코드
함수가 있는 클래스
- 클래스 내에 함수를 또 다른 말로 메서드(Method)라고 한다.
- 클래스 내에 메서드를 구현하는 방식은 다음과 같다.
class 클래스명:
def 함수명(self, 매개변수):
self.변수1 = 값1
self.변수2 = 값2
...
return 반환값
예제
class math:
def addNum(self, a, b):
self.a = a
self.b = b
return a + b
a = math() # a 인스턴스 생성하기
result = a.addNum(10, 20) # 함수 호출하기
print(result)
30
- 인스턴스(실체화된 객체)를 생성한 후, 온점(.) 표시 뒤에 메서드와 매개변수를 입력하면 클래스의 메서드를 호출하여 사용할 수 있다.
self ?
- 위 메서드에서 매개변수로 self를 적었지만, 호출할 때는 self에 해당하는 매개변수를 입력하지 않았다.
- self는 객체 자신을 의미하며, 파이썬에서는 메서드를 호출할 때 이를 호출한 객체 자신을 매개변수로 전달한다.
- 이것은 파이썬의 독특한 특징으로 반드시 명시적으로 구현한다.
생성자 (Constructor)
- 생성자는 객체가 생성될 때 자동으로 호출되어 객체 변수(혹은 속성<attribute>이라고 함)들을 초기화하는 메서드이다.
- 생성자와 같이 __(밑줄 2개)로 이루어진 메서드를 매직 메서드(Magic Method) 혹은 스페셜 메서드(Special Method)라고 하며, 파이썬이 자동으로 호출한다.
- 생성자가 없는 경우에는 인스턴스를 생성하더라도 메서드를 호출해야 객체 변수를 초기화할 수 있다.
- 생성자를 구현하면 인스턴스를 생성함과 동시에 값을 미리 정하기를 원하는 변수를 초기화할 수 있다.
생성자 기본 구조
class 클래스명:
def __init__(self, a, b, ...):
self.a = a
self.b = b
...
- init에 언더스코어(_)가 앞, 뒤로 2개씩 붙어있다.
- 초기화하고자 하는 변수를 매개변수로 설정한다.
생성자 이용하여 변수 초기화
class math:
def __init__(self, a, b):
self.a = a
self.b = b
def addNum(self):
return self.a + self.b
inst = math(10, 20)
print(f"inst.a = {inst.a}, inst.b = {inst.b}")
result = inst.addNum()
print(f"result = {result}")
inst.a = 10, inst.b = 20
result = 30
- 인스턴스를 생성하면서 동시에 변수를 초기화한다.
- addNum에 매개변수를 전달하지 않아도 처음에 초기화한 객체 변수가 그대로 전달되어 결과가 나옴을 알 수 있다.
- 만약 생성자를 구현했음에도 변수를 초기화하지 않으면 다음과 같이 오류가 발생한다.
클래스 상속
- 파이썬 또한 클래스의 기본 특징인 상속이 당연히 가능하다.
- 하위 클래스가 상위 클래스의 기능을 물려받는다.
- 클래스 상속은 다음과 같이 구현한다.
class 하위클래스(상위클래스)
상속 예제
class math:
def __init__(self, a, b):
self.a = a
self.b = b
def addNum(self):
return self.a + self.b
class Num(math):
def printNum(self):
print(f"a = {self.a}, b = {self.b}")
def printResult(self):
print(f"result = {self.addNum()}")
inst = Num(10, 20)
print(f"a = {inst.a}, b = {inst.b}")
inst.printNum()
print("-------------------------")
print(f"result = {inst.addNum()}")
inst.printResult()
a = 10, b = 20
a = 10, b = 20
------------
result = 30
result = 30
- 상위 클래스 math는 변수를 생성하고, 숫자를 더하는 함수를 포함한다.
- 하위 클래스 Num은 math의 기능을 물려받으며, 별도로 숫자 및 연산 결과를 출력하는 기능 또한 갖는다.
오버라이딩 (overriding)
- 하위 클래스는 상위 클래스의 기능을 물려받지만, 이를 수정하는 것이 가능하다.
class math:
def __init__(self, a, b):
self.a = a
self.b = b
def addNum(self):
return self.a + self.b
class Num(math):
def addNum(self):
return 2 * (self.a + self.b) # 더한 값에 2배를 반환하도록 수정(오버라이딩)
inst = Num(10, 20)
print(f"result = {inst.addNum()}")
result = 60
클래스 변수
- 생성자나 메서드로 생성하는 변수가 아니라 클래스 안에서 선언하여 생성하는 변수이다.
- 클래스를 통해 여러 개의 인스턴스를 만들더라도 클래스의 함수는 공유하여 사용하듯이, 클래스 변수 또한 인스턴스들끼리 공유된다.
class Num:
commonNum = 10
num1 = Num()
num2 = Num()
print(f"num1의 commonNum = {num1.commonNum}, num2의 commonNum = {num2.commonNum}")
print("--------------------------------------------------")
# Num 클래스의 commonNum을 수정
Num.commonNum = 20
print(f"num1의 commonNum = {num1.commonNum}, num2의 commonNum = {num2.commonNum}")
num1의 commonNum = 10, num2의 commonNum = 10
--------------------------------------------------
num1의 commonNum = 20, num2의 commonNum = 20
주의
- 클래스 변수를 수정할 때 "클래스명.클래스변수 = 값"으로 작성해야 한다.
- 만약 "인스턴스명.클래스변수 = 값"으로 작성하면, 이는 클래스변수를 수정하는 것이 아니라 클래스변수의 이름과 동일한 새로운 객체 변수를 생성하는 것이 된다.
class Num:
commonNum = 10
num1 = Num()
num2 = Num()
print(f"num1의 commonNum = {num1.commonNum}, num2의 commonNum = {num2.commonNum}")
print("--------------------------------------------------")
# 인스턴스 num1의 commonNum을 수정
num1.commonNum = 20
print(f"num1의 commonNum = {num1.commonNum}, num2의 commonNum = {num2.commonNum}")
num1의 commonNum = 10, num2의 commonNum = 10
--------------------------------------------------
num1의 commonNum = 20, num2의 commonNum = 10
비공개 변수(비공개 속성)
- 클래스 바깥에서는 접근할 수 없고, 오로지 클래스 내부에서만 접근가능한 변수를 생성할 수 있다.
- __(밑줄 2개)를 이용하여 변수를 정의하면 된다.
비공개 변수 접근하기
class private:
def __init__(self, private_var):
self.__private_var = private_var
num = private(1000)
print(num.__private_var)
- 비공개로 설정한 변수는 객체에서 바로 접근할 수 없다.
- 해당 변수는 클래스의 메서드를 통해서 접근할 수 있다.
메서드로 비공개 변수에 접근하기
class private:
def __init__(self, private_var):
self.__private_var = private_var
def extract(self):
return self.__private_var
num = private(1000)
print(num.extract())
1000
비공개 메서드
class private:
def __init__(self, private_var):
self.__private_var = private_var
def __extract(self):
return self.__private_var
num = private(1000)
print(num.__extract())
- 메서드 또한 비공개로 설정할 수 있다.
클래스 변수(클래스 속성)
- 이전에 __init__을 통해 만들었던 변수는 인스턴스(객체)의 변수이며, 클래스만의 변수를 생성할 수 있다.
클래스 변수 생성하기
class Money:
wallet = [] # 클래스 변수 생성
def put_money(self, money):
Money.wallet.append(money) # self가 아닌 클래스명
dollor = Money()
won = Money()
dollor.put_money(10)
won.put_money(10000)
print(dollor.wallet)
print(won.wallet)
print(Money.wallet)
[10, 10000]
[10, 10000]
[10, 10000]
- 클래스 변수는 인스턴스가 모두 공유하므로, 아래와 같은 결과를 얻는다.
- self보다 클래스명을 적어 클래스 변수임을 명시하는 것이 좋다.
비공개 클래스 변수
class Money:
__wallet = []
def put_money(self, money):
Money.__wallet.append(money)
def show(self):
return Money.__wallet
won = Money()
won.put_money(10000)
won.put_money(20000)
print(won.show())
[10000, 20000]
- 클래스 변수도 __를 이용하여 비공개로 설정할 수 있다.
- 이때도 비공개 클래스 변수에 접근하려면 클래스의 메서드를 이용해야 한다.