중급 파이썬 Part 3 - 클래스
객체를 이용한 프로그래밍
#17강. 객체지향 프로그래밍 ( 객체 만들기, 객체 사용의 장점 )
▶ 객체를 이용한 프로그램으로, 객체는 속성과 기능으로 구성된다.
▶ 객체 만들기(생성)
객체는 클래스에서 생성된다. 클래스는 객체를 만들기 위한 틀이다.
▶ 객체 사용의 장점 : 코드 재사용, 모듈화에 좋다.
자동차 장난감 a,b,c를 만들어보자. 가장 효율적인 객체는 배터리 교체형이다. (부품 결합도 낮음)
소프트웨어에서는 부품 결합도가 낮아야한다. 필요할 때 골라 교체해 사용할 수 있다.
# 18. 클래스와 객체 생성 ★★★
객체를 이용한 프로그램으로, 객체는 속성과 기능으로 구성된다.
step 1 ▶ 클래스 만들기
클래스는 class키워드와 속성(변수) 그리고 기능(함수)를 이용해서 만든다.
def do stop - 정지하는 기능 / doStart - 시작하는 기능
step2 ▶ 객체 생성
Q) 비행기 클래스를 만들고 비행기 객체 5개를 생성해보자. --> 소스 비교 (어딨는지 찾아(
class Car:
def __init__(self, col, len):
self.color = col
self.length = len
def doStop(self): #매개변수 self
print('STOP!!')
def doStart(self):
print('START!!')
def printCarInfo(self):
print(f'self.color: {self.color}')
print(f'self.length: {self.length}')
car1 = Car('red', 200)
car2 = Car('blue', 300)
car1.printCarInfo()
car2.printCarInfo()
car1.doStop()
car1.doStart()
#19. 객체 속성 변경
myPC에 데이터를 입력 후 변경
# 20. 객체와 메모리
변수는 객체의 메모리 주소를 저장하고 이를 이용해서 객체를 참조한다.
주소값을 가지고 객체를 참조한다. myCar = Car()
주로 객체를 복사할 때 나타나는 현상
class Robot:
def __init__(self, color, height, weight):
self.color = color
self.height = height
self.weight = weight
def printRobotInfo(self):
print(f'color = {self.color}')
print(f'height = {self.height}')
print(f'weight = {self.weight}')
rb1 = Robot('red', 200, 80)
rb2 = Robot('blue', 300, 120)
rb3 = rb1
rb1.printRobotInfo()
rb2.printRobotInfo()
rb3.printRobotInfo()
rb1.color = 'gray'
rb2.height = 250
rb2.weight = 100
rb1.printRobotInfo()
rb2.printRobotInfo()
rb3.printRobotInfo() # 객체의 주소값이 같아서 (rb1 = rb3) 똑같이 출력
Q) 국어, 영어, 수학 점수를 입력받아 리스트에 저장하고 원본을 유지한 상태로, 복사본을 만들어 과목별 점수를 10% 올렸을 경우에 평균을 출력해 보자. # 다시 풀기
# 21강. 얕은 복사와 깊은 복사
얕은 복사 : 객체 주소를 복사하는 것으로 객체 자체가 복사되지 않는다.
깊은 복사 : 객체 자체를 복사하는 것으로 또 하나의 객체가 만들어진다.
class TemClass:
def __init__(self,n,s):
self.number = n
self.str = s
def print_Class_info(self):
print(f'self.number: {self.number}')
print(f'self.str: {self.str}')
# 얕은 복사
tc1 = TemClass(10, 'Hello')
tc2 = tc1
tc1.print_Class_info()
tc2.print_Class_info()
# 깊은 복사
import copy
tc1 = TemClass(10,'Hello')
tc = copy.copy(tc1)
tc.number = 3.14
tc2.str = 'Bye'
tc1.print_Class_info()
tc.print_Class_info()
자료구조와 알고리즘을 할 때 리스트를 많이 사용한다. append, extend, copy, : 사용
Q) 선수의 원본 점수를 이용해서 평균을 출력하고, 최고값과 최저값을 제외한 평균을 출력하는 프로그램을 만들어보자
origin_score = [8.7, 9.1, 8.9, 9.0, 7.9, 9.5, 8.8, 8.3]
copy_score = origin_score.copy()
origin_score.sort()
copy_score.sort()
copy_score.pop(0) # 첫번째 값을 삭제합니다
copy_score.pop() # 인덱스를 생략한 경우 마지막 값을 삭제합니다
print(f'origin_score : {origin_score}')
print(f'copy_score : {copy_score}')
origin_total = round(sum(origin_score), 2)
origin_avg = round(origin_total/len(origin_score),2)
print(f'Original Total = {origin_total}')
print(f'Original Average = {origin_avg}')
copy_total = round(sum(copy_score),2)
copy_average = round(copy_total/len(copy_score),2)
print(f'Copy Total : {copy_total}')
print(f'Copy Average : {copy_average}')
print(f'origin_avg - copy_average : {round(origin_avg - copy_average,2)}')
# 22강, 상속이란?
클래스는 또다른 클래스를 상속해서 내 것 처럼 사용할 수 있다.
class Normal_Car :
def drive(self):
print('[Normal_Car] drive() called!!')
def back(self):
print('[Normal_Car] back() called!!')
class TurboCar(Normal_Car): # TurboCar는 Normal_Car의 모든 기능을 사용할 수 있다.
def turbo(self):
print('[TurboCar] back() called!!')
myTurboCar = TurboCar()
myTurboCar.turbo()
myTurboCar.drive()
myTurboCar.back()
+ - 가 되는 클래스를 만들고, 이를 상속하는 클래스를 만들어서 * / 기능을 추가해보자
class Calculator_Super:
def add(self, n1, n2):
return n1 + n2
def sub(self, n1, n2):
return n1 - n2
class Calculator_Child(Calculator_Super): # Calculator_Super을 상속받는다.
def mul(self, n1, n2):
return n1 * n2
def div(self, n1, n2):
return n1 / n2
myCalculator = Calculator_Child()
print(myCalculator.add(10,20))
print(myCalculator.sub(10,20))
print(myCalculator.mul(10,20))
print(myCalculator.div(10,20))
#23강. 생성자_01
객체 생성에 대해서 좀 더 자세히 살펴보자
▶ 생성자
객체가 생성될 때 생성자를 호출하면 __init__()가 자동 호출된다.
▶ super()
상위클래스의 속성을 초기화하기 위해서는 super()을 이용한다.
class P_class:
def __init__(self,pNum1, pNum2):
print('[P_class] __init__() called!!')
self.pNum1 = pNum1
self.pNum2 = pNum2
class C_class(P_class):
def __init__(self,cNum1, cNum2):
print('[C_class] __init__() called!')
#P_class.__init__(self, cNum1,cNum2)
super().__init__(cNum1,cNum2)
self.cNum1 = cNum1
self.cNum2 = cNum2
cls = C_class(10,20)
#24강. 생성자_02
객체 생성에 대해서 좀 더 자세히 알아보자.
생성자는 객체가 생성될 때 속성을 초기화 해주는 중요한 기능
생성자를 호출해서 객체를 생성하면 생성자는 자동으로 __init__메소드를 호출해서 객체의 속성을 초기화해줍니다.
Q) 중간고사 클래스와 기말고사 클래스를 상속관계로 만들고 각각의 점수를 초기화하자.
또한 총점 및 평균을 반환하는 기능도 만들어보자.
class MidExam:
def __init__(self, s1, s2, s3): # 3개의 점수 필요 s1, s2, s3
print('[MidExam] __init__()')
self.mid_kor_score = s1
self.mid_eng_score = s2
self.mid_mat_score = s3
def printScore(self):
print(f'mid_kor_score: {self.mid_kor_score}')
print(f'mid_eng_score: {self.mid_eng_score}')
print(f'mid_mat_score: {self.mid_mat_score}')
class EndExam(MidExam):
def __init__(self,s1,s2,s3,s4,s5,s6): # 앞 3개가 중간 , 뒤3개가 기말고사 점수
print('[EndExam] __init__()')
super().__init__(s1,s2,s3) # 3개는 상위클래스로 올려보냄
self.end_kor_score = s4
self.end_eng_score = s5
self.end_mat_score = s6
def printScore(self):
super().printScore()
print(f'end_kor_score: {self.end_kor_score}')
print(f'end_eng_score: {self.end_eng_score}')
print(f'end_mat_score: {self.end_mat_score}')
def getTotalScore(self):
total = self.mid_kor_score +self.mid_eng_score + self.mid_mat_score
total += self.end_kor_score + self.end_eng_score + self.end_mat_score
return total
def getAverageScore(self):
return self.getTotalScore() /6
exam = EndExam(85, 90, 88, 75, 85, 95)
exam.printScore()
print(f'Total: {exam.getTotalScore()}')
print(f'Average: {round(exam.getAverageScore(),2)}')
# 25강. 다중 상속
2개 이상의 클래스를 상속한다.
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()
▶계산기 2개를 상속받아 새로운 계산기를 만들어보자.
--> 몫 구하기
--> 거듭제곱 구하기
# 2개의 클래스를 상속받음
# 26강. 오버라이딩(override) - 재정의
하위클래스에서 상위클래스의 메서드를 재정의 한다.
class Robot:
def __init__(self, c, h, w):
self.color = c
self.height = h
self.weight = w
def fire(self):
print('미사일 발사!')
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): # 오버라이딩 . 상위클래스의 fire()재정의 - 오버라이딩
print('레이저 발사')
myRobot = NewRobot('red',200,300)
myRobot.printRobotInfo() # 상위크래스의 정보
myRobot.fire() # 재정의된 fire()출력
▶삼각형 넓이를 계산하는 클래스를 만들고 이를 상속하는 클래스에서 getArea()를 오버라이딩해서 쿨력결과가 다음과 같을 수 있도록 클래스를 만들어보자.
class TriangleArea :
def __init__(self,w,h):
self.width = w
self.height = h
def printTriangleAreaInfo(self):
print(f'width: {self.width}')
print(f'height: {self.height}')
def getArea(self):
return self.width * self.height / 2
class NewTriangleArea(TriangleArea):
def __init__(self, w,h):
super().__init__(w,h)
def getArea(self):
return str(super().getArea()) + '㎠' # getArea 재정의
ta = NewTriangleArea(7,5)
ta.printTriangleAreaInfo()
triangleArea = ta.getArea()
print(f'triangleArea: {triangleArea}')
#27강. 추상 클래스
상위 클래스에서 하위 클래스로 메서드 구현은 강요한다.
from abc import ABCMeta # 강제구현을 위한 모듈
from abc import abstractmethod # 강제구현을 위한 모듈
class AirPlane(metaclass=ABCMeta): # metaclass 강제 구현
@abstractmethod
def flight(self):
pass # 구현되지 않은 method를 갖고 있다고 해서 추상메서드라고 함
def forward(self):
print('전진')
def backward(self):
print('후진')
class Airliner(AirPlane):
def __init__(self, c):
self.color = c
def flight(self): # 이구문이 없으면 실행 안됨! 강제 구현 필수
print('시속 400km/h 비행')
class flightPlane(AirPlane):
def __init__(self,c):
self.color = c
def flight(self):
print('시속 700km/h 비행!!')
al =Airliner('red')
al.flight()
al.forward()
al.backward()
print('-'*15)
b1 =flightPlane('blue')
b1.flight()
b1.forward()
b1.backward()
추상 클래스는 상속 받았을 때 각자 입맛에 맞춰 바꿔 쓸 수 있음
▶ Q) 계산기 추상 클래스를 만들고 이를 이용해서 새로운 계산기 클래스를 만들어 보자
추상 클래스에는 덧셈, 뺄셈, 곱셈, 나눗셈 기능이 선언되어 있어야 한다.
from abc import ABCMeta # 강제구현을 위한 모듈
from abc import abstractmethod # 강제구현을 위한 모듈
※ 이 게시물은 제로베이스 취업 스쿨 강의를 참고하여 작성된 스터디 노트입니다.