class 키워드와 속성(변수), 기능(함수)를 이용해서 클래스를 구현할 수 있다.
class Car:
def __init__(self,col,len):
self.color = col
self.length = len
def doStop(self):
print('STOP!!')
def doStart(self):
print('START!!')
def printCarInfo(self):
print(f'self.color: {self.color}')
print(f'self.length: {self.length}')
# 생성자 호출 : Car()
car1 = Car('red',200)
car2 = Car('blue',300)
car1.printCarInfo()
car2.printCarInfo()
car1.doStop()
car1.doStart()
class Airplane:
def __init__(self,col,len, wt):
self.color = col
self.length = len
self.weight = wt
def doLand(self):
print('착륙합니다.')
def doDepart(self):
print('이륙합니다.')
def printAirInfo(self):
print(f'self.color: {self.color}')
print(f'self.length: {self.length}')
print(f'self.weight: {self.weight}')
air1 = Airplane('red',72,120000)
air2 = Airplane('blue',80,160000)
air3 = Airplane('white',77,130000)
air4 = Airplane('wine',88,180000)
air5 = Airplane('yellow',73,125000)
정의된 객체의 속성은 변경할 수도 있다.
class Airplane:
def __init__(self,col,len, wt):
self.color = col
self.length = len
self.weight = wt
def doLand(self):
print('착륙합니다.')
def doDepart(self):
print('이륙합니다.')
def printAirInfo(self):
print(f'self.color: {self.color}')
print(f'self.length: {self.length}')
print(f'self.weight: {self.weight}')
air1 = Airplane('red',72,120000)
# air1의 객체 속성 변경
air1.color = 'purple'
air1.length = 75
air.weight = 130000
air.printAirInfo() # -> 변경된 정보를 확인할 수 있다.
얕은 복사는 객체 주소를 복사하는 것, 객체 자체가 하나 더 생기는 것이 아니다.
깊은 복사는 기존의 객체 자체를 하나 더 복사하는 것이다.
아래 식처럼 사용할 경우, 얕은 복사가 된다.
tc1 = TemCls(10,'hello')
tc2 = tc1
얕은 복사는 tc2의 속성을 변경시키면 tc1의 속성도 함께 변경된다.
깊은 복사를 구현하는 방식은 여러가지가 있다.
import copy
tc1 = TemCls(10,'hello')
tc2 = copy.copy(tc1) # tc1가 가리키는 객체와 tc2가 가리키는 객체가 달라지게 된다.
깊은 복사는 tc2의 속성을 변경시켜도 tc1의 값에 영향을 주지 않는다.
리스트에서의 복사 활용하기
리스트에서는 기본적으로 id() 라는 함수로 객체의 메모리 주소를 확인할 수 있다.
2-1. 얕은 복사
# 얕은 복사
scores = [9,8,7,6,5,4]
copyScores = scores
print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')
#id(scores): 4333407680
#id(copyScores): 4333407680
2-2. 깊은 복사
# 깊은 복사
# 1. for 구문, append()
copyScores = []
for s in scores:
copyScores.append(s)
print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')
#id(scores): 4376186432
#id(copyScores): 4376307584
```python
----------------------------------------------------------
# 2. extend()
copyScores.extend(scores)
print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')
#id(scores): 4336315968
#id(copyScores): 4336690688
------------------------------------------------------------
# 3. copy() : 리스트 내장 깊은 복사 함수
copyScores = scores.copy()
print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')
#id(scores): 4338250176
#id(copyScores): 4338250304
------------------------------------------------------------
# 4. 슬라이싱 : [:]
copyScores = scores[:]
print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')
#id(scores): 4368101760
#id(copyScores): 4368101888
클래스는 또 다른 클래스를 상속해서 안에 있는 기능들을 사용할 수 있다.
class First:
def go(self):
print(f'[First] go() called!')
def back(self):
print(f'[First] back() called!')
class Second(First): # 클래스 상속
def second(self):
print(f'[Second] go() called!')
mySecond = Second()
mySecond.second()
mySecond.go()
mySecond.back()
#[Second] go() called!
#[First] go() called!
#[First] back() called!
class AddSub:
def add(self,n1,n2):
return n1 + n2
def sub(self,n1,n2):
return n1 - n2
class MulDiv(AddSub):
def mul(self,n1,n2):
return n1 * n2
def div(self,n1,n2):
return n1 / n2
cal = MulDiv()
print(f'cal.add(10,20) : {cal.add(10,20)}')
print(f'cal.sub(10,20) : {cal.sub(10,20)}')
print(f'cal.mul(10,20) : {cal.mul(10,20)}')
print(f'cal.div(10,20) : {cal.div(10,20)}')
#cal.add(10,20) : 30
#cal.sub(10,20) : -10
#cal.mul(10,20) : 200
#cal.div(10,20) : 0.5
class Calculator():
def __init__(self):
print(f'[Calculator] __init__() called!')
cal = Calculator() # 객체 생성 및 생성자 호출
# [Calculator] __init__() called!
init 의 역할
: 속성을 초기화해준다.
< 외부에서 매개변수로 값을 받아오는 방식>
class Calculator():
def __init__(self,n1,n2):
print(f'[Calculator] __init__() called!')
self.num1 = n1
self.num2 = n2
cal = Calculator(10,20) # 객체 생성 및 생성자 호출
print(cal.num1)
print(cal.num2)
< 내부에서 값을 고정시키는 방식>
class Calculator():
def __init__(self):
print(f'[Calculator] __init__() called!')
self.num1 = 10
self.num2 = 100
cal = Calculator()
print(cal.num1)
print(cal.num2)
< 혼합 >
class Calculator():
def __init__(self,n):
print(f'[Calculator] __init__() called!')
self.num1 = n
self.num2 = 100
cal = Calculator(3.14) # 객체 생성 및 생성자 호출
print(cal.num1)
print(cal.num2)
상위 클래스 속성 초기화하기 - super()
부모 - 자식 클래스 간 상속이 되어 있을 경우, 기능은 특별한 조건 없이 사용할 수 있지만, 속성의 경우에는 부모 속성을 사용하고 싶다면 super() 메소드를 넣어줘야 한다.
class Parent():
def __init__(self,pnum1,pnum2):
print(f'[Pclass] __init__() called!')
self.pnum1 = pnum1
self.pnum2 = pnum2
class Child():
def __init__(self,cnum1,cnum2):
print(f'[Cclass] __init__() called!')
# 부모 클래스 init 호출하여 속성값 초기화해주기
super().__init__(cnum1,cnum2)
self.cnum1 = cnum1
self.cnum2 = cnum2
cls = Child(10,20)
# [Cclass] __init__() called!
#[Pclass] __init__() called!
class Car01:
def drive(self):
print('drive() method called!')
class Car02:
def turbo(self):
print('turbo() method called!')
class Car03:
def fly(self):
print('fly() method called!')
class Car(Car01, Car02, Car03): # 다중 상속
def __init__(self):
pass
Mycar = Car()
Mycar.drive()
Mycar.turbo()
Mycar.fly()
#drive() method called!
#turbo() method called!
#fly() method called!
두 클래스가 종속관계에 있을 때, 하위 클래스가 상위 클래스의 메서드를 재정의하게 되는 경우를 의미한다.
[예시]
class Robot:
def __init__(self,c,h,w):
self.color = c
self.height = h
self.weight = w
def fire(self):
print(f'미사일 발사!')
def printRobotInfo(self):
print(f'self.color : {self.color}')
print(f'self.height : {self.height}')
print(f'self.weight : {self.weight}')
class NewRobot(Robot):
def __init__(self,c,h,w):
super().__init__(c,h,w)
def fire(self): # 오버라이딩
print('레이저 발사!')
myRobot = NewRobot('red',200,300)
myRobot.printRobotInfo()
myRobot.fire()
상위 클래스에서 하위 클래스에 메서드 구현을 강요하는 방법을 일컫는다
추상 클래스의 활용 기능은 상위 클래스에서 선언만 해준 메서드를 서로 다른 하위 클래스에서 입맛에 맞게 변경할 수 있다는데 있다.
추상클래스를 구현하는데 필요한 모듈은 abc 안의 ABCMeta, abstractmethod 함수다.
[예시]
#################### 1 #####################
from abc import ABCMeta
from abc import abstractmethod
class AirPlane(metaclass=ABCMeta):
@abstractmethod
def flight(self):
pass # 구현되지 않은 메소드
def forward(self):
print('전진!')
def backward(self):
print('후진!')
class Airliner(AirPlane):
def __init__(self,c):
self.color = c
def flight(self):
print('시속 400km/h 비행!')
al = Airliner('red')
al.flight()
al.forward()
al.backward()
#################### 2 #####################
# 계산기 추상 클래스 -> 새로운 계산기 클래스를 생성하기
# 덧셈 , 뺄셈, 곱셈, 나눗셈 기능이 있어야 함
from abc import ABCMeta
from abc import abstractmethod
class Calculator(metaclass=ABCMeta):
@abstractmethod
def add(self,n1,n2):
pass
def sub(self,n1,n2):
pass
def mul(self,n1,n2):
pass
def div(self,n1,n2):
pass
class Newcalculator(Calculator):
def add(self,n1,n2):
return n1 + n2
def sub(self,n1,n2):
return n1 - n2
def mul(self,n1,n2):
return n1 * n2
def div(self,n1,n2):
return n1 / n2
value = Newcalculator()
print(value.add(10,20))
print(value.sub(10,20))
print(value.mul(10,20))
print(value.div(10,20))
여기까지 객체지향 프로그래밍의 개념과 클래스 개념, 활용 방법들을 살펴봤다. 다음 포스팅은 try ~ except 예외 처리 구문 및 활용 방법들에 대해서 정리해볼 예정이다.