230904_스터디노트

Sihyun Kim·2023년 9월 4일

객체와 메모리

  • 특정 클래스에서 생성자를 호출해서 객체를 만들면 메모리에 객체가 생성됨
  • 사용하기 위해 변수를 생성하여 변수에 객체를 할당하여 사용
  • 사실 변수에는 객체 데이터 그 자체가 저장되는게 아니라, 객체의 메모리의 주소가 저장이 됨

객체와 메모리 (실습)

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

print(scores)

copiedScores = scores.copy()

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

avg = sum(scores)/len(scores)
afterAvg = sum(copiedScores)/len(copiedScores)

print(f'이전 평균: {round(avg, 2)}')
print(f'이후 평균: {round(afterAvg, 2)}')
  • 안 배운거 또 실습에서 불쑥불쑥 나오기 있기없기 ^^
  • avg 변수 안만들고 그냥 print 할 때 계산하면서 round까지 하려고 했는데,
    뭐가 문제인지 자꾸 오류가 나서 결국 변수 따로 만들어서 round 해줌

💀 오늘 처음 만난 idx, enumerate(열거하다)

for idx, score in enumerate(copiedScores):
    score *= 1.1
    copiedScores[idx] = 100 if score > 100 else score
  • 리스트 값을 열거해서 하나씩 달라지게 만들어야 할 때 (여기서는 10% 증가) 사용
  • 국영수 점수라서 10% 증가 시에 100점이 넘으면 안되니까, 100 넘으면 100으로 표시
  • if - else를 저렇게 한 줄로 쓰는 것도 첫 등장

얕은 복사와 깊은 복사

  • 얕은 복사: 객체 주소를 복사하는 것으로 객체 자체가 복사되지 않는다
  • 깊은 복사: 객체 자체를 복사하는 것으로 또 하나의 객체가 만들어진다
import copy

scores = [10, 2, 4, 34, 5, 9]
copiedScores = []

copiedScores = scores            	#얕은 복사
for s in scores:                    #깊은 복사 1
    copiedScores.append(s)

copiedScores = scores.copy()        #깊은 복사 2

copiedScores = scores[:]            #깊은 복사 3 (슬라이스)

copiedScores = scores.extend()      #깊은 복사 4
#id확인
print(f'{id(scores)}')
print(f'{id(copiedScores)}')

#얕은 복사는 같은 id 출력, 깊은 복사는 다른 id 출력

🙄 슬라이스는 무엇인가

list = [5 , 10, 15, 20, 25, 30]
alist = list[0:3]     #인덱스 0부터 3개까지 잘라서 새 리스트를 만든다
print(alist)  		  #[5, 10 ,15]

얕은 복사와 깊은 복사 (실습)

#.sort() 

list2 = [8, 4, 7, 12, 9]
list2.sort()
print(list2)		#[4, 7, 8, 9, 12]

list2.sort(reverse=True)
print(list2)		#[12, 9, 8, 7, 4]
#.pop() 리스트의 맨 마지막 값 삭제
list3 = [24, 50, 45, 72, 9]

list3.pop()
print(list3)		#[24, 50, 45, 72]

#.pop(n) 리스트의 n번째 인덱스값 삭제
list3.pop(2)
print(list3)		#[24, 50, 72]

👆 문제 풀기 전에 알아야 하는 것

originalScore = [8.7, 9.1, 8.9, 9.0, 7.9, 9.5, 8.8, 8.3]
copiedScore = originalScore.copy()

copiedScore.sort()
copiedScore.pop()
copiedScore.pop(0)


originalSum = sum(originalScore)
originalAvg = originalSum / len(originalScore)

copiedSum = sum(copiedScore)
copiedAvg = copiedSum / len(copiedScore)

print(f'원본 평균: {round(originalAvg,2) }')
print(f'수정 평균: {round(copiedAvg,2)}')

클래스 상속

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

class CalculatorAddSub:

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

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


class CalculatorMulDiv(CalculatorAddSub):       #덧셈 뺄셈 기능을 상속받자! (...좋겠다)

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

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


result = CalculatorMulDiv()

print(result.add(10,20))
print(result.sub(10,20))
print(result.mul(10,20))
print(result.div(10,20))

생성자 (01)

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

    cal = Calulator() 👉 Calculator() 생성자 호출 👉 Calculator() __init() 호출

class Calculator:

    def __init__(self):
        print('[Calculator] __init__() called!')

cal = Calculator()
class Calculator:

    def __init__(self, n1):
        print('[Calculator] __init__() called!')
        self.number1 = n1
        self.number2 = 5

cal = Calculator(10)

cal.number2 = 20

result = cal.number1+cal.number2
print(result)  #30
  • 상속을 받았을 때 기능은 바로 쓸 수 있으나, 속성은 상위 클래스의 init()를 가져와야 함

🔑 방법1 (강제 호출)

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)  	#강제로 호출하기
        

        self.cNum1 = cNum1
        self.cNum2 = cNum2


ref = C_Class(10,20)

🔑 방법2 (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!')

        super().__init__(cNum1, cNum2)		#세련되게 호출하기

        self.cNum1 = cNum1
        self.cNum2 = cNum2


ref = C_Class(10,20)

생성자 (02)

class MidExam:

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

        self.midKor = s1
        self.midEng = s2
        self.midMat = s3

    def printScore(self):
        print(f'중간 국어: {self.midKor}')
        print(f'중간 영어: {self.midEng}')
        print(f'중간 수학: {self.midMat}')

class FinalExam(MidExam):

    def __init__(self, s1, s2, s3, s4, s5, s6):
        print('[FinalExam] __init__()')

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

        self.finKor = s4
        self.finEng = s5
        self.finMat = s6

    def printScore(self):

        super().printScore()

        print(f'기말 국어: {self.finKor}')
        print(f'기말 영어: {self.finEng}')
        print(f'기말 수학: {self.finMat}')

    def getTotalScore(self):
        total = self.midKor + self.midEng + self.midMat
        total += self.finKor + self.finEng + self.finMat
        return total

    def getAvgScore(self):
        return self.getTotalScore()/6

result = FinalExam(85, 98, 87, 65, 67, 69)

result.printScore()
print(f'총점: {result.getTotalScore()}')
print(f'평균: {result.getAvgScore()}')
  • 처음에 init()만 super()해서 프린트가 기말만 나옴!
  • total 구할 때, 중간 기말 구분해서 두 줄로 써주는게 인상적
profile
문과이과예체능통합형인재

0개의 댓글