카테고리 없음

중급 파이썬 Part 3 - 클래스

닥터 마틸다 2023. 3. 15. 14:25

객체를 이용한 프로그래밍

#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   # 강제구현을 위한 모듈

 

※ 이 게시물은 제로베이스 취업 스쿨 강의를 참고하여 작성된 스터디 노트입니다.