[Python] 중급
객체와 메모리
얕은복사와 깊은복사
클래스 상속
생성자
super()
다중 상속
오버라이딩
추상클래스
- 객체와 메모리
변수는 객체의 메모리 주소를 저장하고,
이를 이용해서 객체를 참조한다.
➜ 별개의 객체를 만들고 싶다면 copy함수이용
- 얕은 복사와 깊은 복사
-얕은 복사란:객체 주소를 복사하는 것으로,
객체 자체가 복사되지 않는다.
(기존 객체의 속성 변경시,복사된 객체의 속성도 변함)
(객체 주소가 같으므로 같은 객체 )
-깊은 복사란:객체 자체를 복사하는 것으로,
또 하나의 객체가 만들어진다.
(기존 객체와 복사된 객체의 주소는 다름))class TemCls: def __init__(self,n,s): self.number = n self.str =s def printClsInfo(self): print(f'self.number : {self.number}') print(f'self.str : {self.str}') #얕은복사 tc1 = TemCls(10,'Hello') tc2 =tc1 tc1.printClsInfo() tc2.printClsInfo() tc2.number =3.14 tc2.str ='Bye' tc1.printClsInfo() tc2.printClsInfo() #이때 결과 값으로, 두 변수의 값은 변경됨 #깊은 복사 import copy tc1 = TemCls(10,'Hello') tc2 = copy.copy(tc1) tc1.printClsInfo() tc2.printClsInfo() tc2.number = 3.14 tc2.str ='Bye' tc1.printClsInfo() tc2.printClsInfo() #이때 기존 값은 유지, 변경된 변수만 값 변경import copy scores=[9,8,5,7,6,10] scoresCopy = [] #얕은복사 scoresCopy = scores print(f'id(scoresCopy) : {id(scoresCopy)}') print(f'id(scores) : {id(scores)}') #깊은 복사 #for문 사용 for s in scores: scoresCopy.append(s) print(f'id(scoresCopy) : {id(scoresCopy)}') print(f'id(scores) : {id(scores)}') # extend사용 scoresCopy.extend(scores) print(f'id(scoresCopy) : {id(scoresCopy)}') print(f'id(scores) : {id(scores)}') #copy사용 scoresCopy=scores.copy() print(f'id(scoresCopy) : {id(scoresCopy)}') print(f'id(scores) : {id(scores)}') # 슬라이싱 사용 scoresCopy = scores[:] print(f'id(scoresCopy) : {id(scoresCopy)}') print(f'id(scores) : {id(scores)}')
클래스 상속
- 클래스는
또 다른 클래스를 상속해서 내 것처럼 사용할 수 있다.
class Calculaotr(): def add(self,n1,n2): return n1+n2 def sub(self,n1,n2): return n1-n2 class CalculatorChild(Calculator): def mul(self,n1,n2) return n1*n2➜ 상속받을 클래스를 사용하기 위해서는,
class 신규 클래스명(상속받을 클래스명)으로 작성하기
➜ 신규 클래스에서는 mul기능만 사용 가능했으나,
상속 받은 이후에는 add/sub 기능 모두 사용 가능 하다.
생성자
- 객체가 생성될 때, 생성자를 호출하면
__init__()가 자동 호출된다.
- __init__()가 속성을 초기화 한다.
#매개변수 n1,n2에 그때그때 값이 달라지진다. class Calculator: def __init__(self,n1,n2): print('[Calculator] __init__() called!!') self.num1=n1 self.num2=n2 cal =Calculator(10,20) print(f'cal.num1 : {cal.num1}') print(f'cal.num2 : {cal.num2}') #매개변수 n1,n2가 10과 100으로 값이 초기화된다 . class Calculator: def __init__(self): print('[Calculator] __init__() self.num1 = 10 self.num2=100 cal =Calculator() #매개변수로 값을 받지 않는다. print(f'cal.num1 : {cal.num1}') print(f'cal.num2 : {cal.num2}')
- super()
상위 클래스의 속성을 초기화하기 위해서 super()를 이용한다.
➜ super().__init__(100,200)대신에
P_Class.__init__(self,100,200)으로 넣어줘도된다.
➜ super().사용시에, self변수는 기입 안해도 됨
- 다중 상속
2개 이상의 클래스를 상속한다.class Calculator: def add(self,n1,n2): return n1 + n2 class Calculator2: def mod(self,n1,n2): return n1 % n2 class MyCalculator(Calculator,Calculator2): ... ...➜다중 상속을 받을때에는,
신규 class명(상속받을 클래스1,상속받을 클래스2)
- 오버라이딩
하위 클래스에서 상위 클래스의 메서드를
재정의(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): print('레이저 발사!') myRobot=NewRobot('red',200,300) myRobot.printRobotInfo() myRobot.fire()➜ NewRobot클래스에서 Robot클래스를 상속받은 뒤,
fire()기능을 오버라이딩
'미사일 발사' ➜ '레이저 발사'
추상클래스
상위 클래스에서 하위 클래스에 메서드 구현을 강요한다.
➜ 상위 클래스에서 메서드 선언부만 있으며, 실행부가 없다.
➜ 상속받는 하위 클래스에서 해당 메서드의 실행부를 구체화 해야함.from abc import ABCMeta from abc import abstractmethod class AriPlane(metaclass=ABCMeta): @abstractmethod def flight(self): pass def forward(self): print('전진') def backward(self): print('후진') class Airliner(AriPlane): def __init__(self,c): self.color = c def flight(self): print('시속 400km/h 비행!!') al=Airliner('red') al.flight() al.forward() al.backward()➜ 추상클래스를 위해서는,
metaclass와 데코레이션을 꼭 선언해줘야한다.