파이썬 26, 27, 28, 29

윤선민·2023년 12월 5일

파이썬

목록 보기
9/14

19_객체 속성 변경

객체의 속상은 변경할 수 있다.

class Calculator:

    def __int__(self):
        self.number1 = 0
        self.number2 = 0
        self.result = 0

    def add(self):
        self.result = self.number1 +self.number2
        return self.result

    def sub(self):
        self.result = self.number1 - self.number2
        return self.result

    def mul(self):
        self.result = self.number1 * self.number2
        return self.result

    def div(self):
        self.result = self.number1 / self.number2
        return self.result

calculator = Calculator()
calculator.number1 = 10
calculator.number2 = 20

print(f'calculator.add(): {calculator.add()}')
print(f'calculator.sub(): {calculator.sub()}')
print(f'calculator.mul(): {calculator.mul()}')
print(f'calculator.div(): {calculator.div()}')
==============================================================
calculator.add(): 30
calculator.sub(): -10
calculator.mul(): 200
calculator.div(): 0.5

20_객체와 메모리

변수는 개체의 메모리 주소를 저장하고 이를 이용해서 객체를 참조한다.

scores = [int(input('국어 점수 입력: ')),
          int(input('영어 점수 입력: ')),
          int(input('수학 점수 입력: '))]

# print(scores)

copyScores = scores.copy()

for idx, score in enumerate(copyScores):
    result = score * 1.1
    copyScores[idx] = 100 if result > 100 else result

print(f'이전 평균: {round(sum(scores) / len(scores), 2)}')
print(f'이후 평균: {round(sum(copyScores) / len(copyScores), 2)}')
==========================================================================
국어 점수 입력: 77
영어 점수 입력: 82
수학 점수 입력: 91
이전 평균: 83.33
이후 평균: 91.63

21_얕은복사와 깊은복사

얕은복사

객체 주소를 복사하는 것으로 객체 자체가 복사되지 않는다.(객체유지)

깊은복사

객체 자체를 복사하는 것으로 또 하나의 객체가 만들어진다.(객체가 하나 더 복사됨)

scores = [9, 8, 5, 7, 6, 10]
scoresCopy = []


scoresCopy = scores
print(f'id(scores): {id(scores)}')
print(f'id(scoresCopy): {id(scoresCopy)}')


for s in scores:
    scoresCopy.append(s)
print(f'id(scores): {id(scores)}')
print(f'id(scoresCopy): {id(scoresCopy)}')


scoresCopy.extend(scores)
print(f'id(scores): {id(scores)}')
print(f'id(scoresCopy): {id(scoresCopy)}')


scoresCopy = scores.copy()
print(f'id(scores): {id(scores)}')
print(f'id(scoresCopy): {id(scoresCopy)}')


scoresCopy = scores[:]
print(f'id(scores): {id(scores)}')
print(f'id(scoresCopy): {id(scoresCopy)}')
plaOriSco = [8.7, 9.1, 8.9, 9.0, 7.9, 9.5, 8.8, 8.3]
plaCopSco = plaOriSco.copy()

plaOriSco.sort() #오름차순으로 정렬
plaCopSco.sort()

plaCopSco.pop(0) #첫번째원소 제거
plaCopSco.pop() #마지막원소 제거

print(f'plaOriSco: {plaOriSco}')
print(f'plaCopSco: {plaCopSco}')


oriTot = round(sum(plaOriSco), 2)
oriAvg = round(oriTot / len(plaOriSco), 2)
print(f'Original Total: {oriTot}')
print(f'Original Average: {oriAvg}')

copTot = round(sum(plaCopSco), 2)
copAvg = round(oriTot / len(plaCopSco), 2)
print(f'Copy Total: {copTot}')
print(f'Copy Average: {copAvg}')


print(f'oriAvg - copAvg: {oriAvg - copAvg}')
======================================================
plaOriSco: [7.9, 8.3, 8.7, 8.8, 8.9, 9.0, 9.1, 9.5]
plaCopSco: [8.3, 8.7, 8.8, 8.9, 9.0, 9.1]
Original Total: 70.2
Original Average: 8.78
Copy Total: 52.8
Copy Average: 11.7
oriAvg - copAvg: -2.92

22_클래스 상속

상속이란 또 다른 클래스를 상속해서 내 것처럼 사용할 수 있다.

class CalculatorSuper:

    def add(self, n1, n2):
        return n1 + n2

    def sub(self, n1, n2):
        return n1 - n2

class CalculatorChild(CalculatorSuper):

    def mul(self, n1, n2):
        return n1 * n2

    def div(self, n1, n2):
        return n1 / n2

cal = CalculatorChild()

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

23_생성자 (01)

객체가 생성될 때 생성자를 호출하면 init()가 자동 호출된다.

init() 매서드

속성을 초기화한다.
1. 클래스의 인스턴스가 생성될 때 자동으로 호출
2. self 매개변수를 사용하여 인스턴스 자신을 나타낸다. self는 관례적으로 사용되는 이름이며, 다른 이름을 사용해도 된다.
3. 인스턴스를 초기화하는 코드를 포함할 수 있다. 이를 통해 인스턴스의 속성을 초기화하거나 다른 초기화 작업을 수행할 수 있다.

super()

상위 클래스의 속성을 초기화하기 위해서 super()를 이용한다.

클래스명init하면 초기화 가능

24_생성자 (02)

class MidExam:

    def __init__(self, s1, s2, s3):
        print('[MidExam] __init__()')

        self.mid_kor_score = s1
        self.mid_eng_score = s2
        self.mid_mat_score = s3

    def printScores(self):
        print(f'mid_kor_score: {self.mid_kor_score}')
        print(f'mid_emg_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):
        print('[EndExam] __init__()')

        super().__init__(s1, s2, s3)

        self.end_kor_score = s4
        self.end_eng_score = s5
        self.end_mat_score = s6

    def printScores(self):
        super().printScores()
        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.printScores()

print(f'Total: {exam.getTotalScore()}')
print(f'Average: {round(exam.getAverageScore(), 2)}')
======================================================================
[EndExam] __init__()
[MidExam] __init__()
mid_kor_score: 85
mid_emg_score: 90
mid_mat_score: 88
end_kor_score: 75
end_eng_score: 85
end_mat_score: 95
Total: 518
Average: 86.33

25_다중 상속

2개 이상의 클래스를 상속한다.

❗주의❗ 남발해서 사용하면 혼란스러울 수 있음

class BasicCalculatoer:

    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

class DeveloperCalculator:

    def mod(self, n1, n2):
        return n1 % n2

    def flo(self, n1, n2):
        return n1 // n2

    def exp(self, n1, n2):
        return n1 ** n2


class NewCalculator(BasicCalculatoer, DeveloperCalculator):
    def __init__(self):
        pass

cal = NewCalculator()
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)}')

print(f'cal.mod(10, 20): {cal.mod(10, 20)}')
print(f'cal.flo(10, 20): {cal.flo(10, 20)}')
print(f'cal.exp(10, 20): {cal.exp(10, 20)}')
==================================================================
cal.add(10, 20): 30
cal.sub(10, 20): -10
cal.mul(10, 20): 200
cal.div(10, 20): 0.5
cal.mod(10, 20): 10
cal.flo(10, 20): 0
cal.exp(10, 20): 100000000000000000000

26_오버라이딩

하위 클래스에서 상위 클래스의 매서드를 재정의(overrie)한다.

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()) + 'cm2'


ta = NewTriangleArea(7, 5)
ta.printTriangleAreaInfo()
triangleArea = ta.getArea()
print(f'TriangleArea: {triangleArea}')
=======================================================
width: 7
height: 5
TriangleArea: 17.5cm2

27_추상클래스

상위클래스에서 하위 클래스에 메서드 구현을 강요한다.

from abc import ABCMeta
class Calculator(metaclass=ABCMeta):  #ABCMeta를 사용하려면 from abc import ABCMeta를 실행해야됨! 안하면 ABCMeta정의 안되어 있어서 오류뜸

    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 ChildCalculator(Calculator):

    def add(self, n1, n2):
        print(n1 + n2)

    def sub(self, n1, n2):
        print(n1 - n2)

    def mul(self, n1, n2):
        print(n1 * n2)

    def div(self, n1, n2):
        print(n1 / n2)

childCal = ChildCalculator()
childCal.add(10, 20)
childCal.sub(10, 20)
childCal.mul(10, 20)
childCal.div(10, 20)


class DeveloperCalculator(Calculator):

    def add(self, n1, n2):
        print(n1 + n2)

    def sub(self, n1, n2):
        print(n1 - n2)

    def mul(self, n1, n2):
        print(n1 * n2)

    def div(self, n1, n2):
        print(n1 / n2)

    def mod(self, n1, n2):
        print(n1 % n2)

    def flo(self, n1, n2):
        print(n1 // n2)


devCal = DeveloperCalculator()
devCal.add(10, 20)
devCal.sub(10, 20)
devCal.mul(10, 20)
devCal.div(10, 20)
devCal.mod(10, 20)
devCal.flo(10, 20)
======================================
30
-10
200
0.5
30
-10
200
0.5
10
0

28_예외란?

  • 문법적인 문제는 없으나 실행 중 발생하는 예상하지 못한 문제.
  • 예외 관련 클래스는 Exception 클래스를 상속한다.

29_예외처리

예상하지 못한 예외가 프로그램 전체 실행에 영향이 없도록 처리함.

try ~ except

예외 발생 예상 구문을 try ~ except로 감싼다.

nums = []

n = 1
while n < 6:
    try:
        num = int(input('input number: '))
    except:
        print('예외 발생!')
        continue

    nums.append(num)
    n += 1

print(f'nums: {nums}')
========================================
input number: 10
input number: 8
input number: 5
input number: r
예외 발생!
input number: 1
input number: 5
nums: [10, 8, 5, 1, 5]

30_try ~ except ~ else

~else

예외가 발생하지 않은 경우에 실행하는 구문

eveList = []; oddList = []; floatList = []

n = 1
while n < 6:

    try:
        num = float(input('input number: '))

    except:
        print('exception raise!!')
        print('input number again!!')
        continue

    else:

        if num - int(num) != 0:
            print('float number!')
            floatList.append(num)
        else:
            if num % 2 == 0:
                print('even number!')
                eveList.append(int(num))

            else:
                print('odd number')
                oddList.append(int(num))

        n += 1

print(f'eveList: {eveList}')
print(f'oddList: {oddList}')
print(f'floatList: {floatList}')
=======================================================
input number: 5
odd number
input number: 4
even number!
input number: 1
odd number
input number: 3.14
float number!
input number: 11.1
float number!
eveList: [4]
oddList: [5, 1]
floatList: [3.14, 11.1]

31_finally

예외 발생과 상관없이 항상 실행한다.

eveList = []; oddList = []; floatList = []; dataList = []


n = 1
while n < 6:

    try:
        data = input('input number: ')
        floatNum = float(data)

    except:
        print('exception raise!!')
        print('input number again!!')
        continue

    else:

        if floatNum - int(floatNum) != 0:
            print('float number!')
            floatList.append(floatNum)
        else:
            if floatNum % 2 == 0:
                print('even number!')
                eveList.append(int(floatNum))

            else:
                print('odd number')
                oddList.append(int(floatNum))

        n += 1

    finally:
        dataList.append(data)


print(f'eveList: {eveList}')
print(f'oddList: {oddList}')
print(f'floatList: {floatList}')
print(f'dataList: {dataList}')
======================================================
input number: 안녕
exception raise!!
input number again!!
input number: 1
odd number
input number: 2
even number!
input number: 2.1
float number!
input number: 3
odd number
input number: 4
even number!
eveList: [2, 4]
oddList: [1, 3]
floatList: [2.1]
dataList: ['안녕', '1', '2', '2.1', '3', '4']

32_Exception 클래스

Exception

예외 담당 클래스

raise

예외를 발생시킬 수 있다.

이 글은 제로베이스 데이터 분석 스쿨의 강의 자료 일부를 발췌하여 작성되었습니다.

파이썬 기초는 정말 말그대로 기초였다😂 기초는 뭐든지 재밌게 할 수 있었는데 중급에 들어오니 점점 따라잡기 벅차다..! 이해안되는것부터 이해하고 한땀 한땀 코드를 따라하려다보니 시간도 많이 걸린다. 처음이라 힘든거겠지,,,.·´¯(>▂<)´¯·. 익숙해질때까지 반복하자...!

0개의 댓글