[ZB] 파이썬 중급 3

SeriesWorld·2023년 10월 25일

ZB20

목록 보기
7/9
post-thumbnail

객체지향 프로그래밍

  • class를 통해 객체를 만들고, 속성과 기능을 만들어 사용할 수 있다.
  • 객체를 사용하는 경우 코드 재사용, 모듈화에 좋다.

속성

  • 객체가 가지는 속성(예를 들어, 자동차 클래스는 색상, 길이, 가격 등등의 속성을 가질 수 있다.)
  • 객체를 만들 때 각각의 속성이 무엇인지 설장할 수 있고, 설정하지 않는 경우 기본값을 지정할 수 있다.

기능(메서드)

  • 객체가 할 수 있는 행동(?) 같은 개념 (자동차 클래스 예로 전진, 후진 등의 기능을 가질 수 있다)
  • 그 객체가 가지는 함수라고 볼 수 있다.

  • class 안의 특정 기능은 매개변수로 self를 받는다.
class Car:

	def __init__(self, col, len):   # 생성자, Car()와 대응되는 메써드
       	self.color = col
       	self.length = len

    def doStop(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)
car1.doStop()   # Stop!!
car1.printCarInfo()   # self.color: red \n self.length: 200

객체의 속성 변경

car1.color = 'white'
car1.printCarInfo()   # self.color: white \n self.length: 200
  • 객체의 속성은 값을 입력(대응연산자 '=')함으로써 수정할 수 있다.(변수처럼)

객체와 메모리

  • 객체를 담는 변수는 실제 객체가 저장된 메모리의 '주소값'을 저장하고 있다.
    (객체의 속성을 바꾸는 경우 메모리와 상관없이 실제 객체의 메모리 데이터가 바뀐다)

얕은 복사

  • 객체 주소를 복사하는 것

깊은 복사

  • 객체 자체를 복사하는 것으로, 또 하나의 객체가 만들어진다.(copy 모듈, copy.copy(객체)로 복사 가능)
import copy
class Car:

	def __init__(self, color):
        self.color = color
        
    def printCarInfo(self):
      	print(f'{self.color}')

car1 = Car('red')
car2 = car1  				# 얕은 복사
car3 = copy.copy(car1) 		# 깊은 복사

car1.printCarInfo()   # red
car2.printCarInfo()   # red
car3.printCarInfo()   # red
    
car1.color = 'blue'

car1.printCarInfo()   # blue
car2.printCarInfo()   # blue
car3.printCarInfo()   # red
  • 다음과 같은 방법으로 깊은 복사를 할 수 있다.
  1. copy.copy() 메서드 활용
  2. for문 활용 (빈 리스트 선언 후 for문을 통해 각 값을 append)
  3. extend() 메서드 활용
  4. 슬라이싱([:]) 활용

강의에서는 위 방법이 깊은 복사라고 소개되었고, 실제로 각각 복사했을 때 id값이 다른 것을 확인할 수 있었다.
하지만 찾아보니 각 방법에는 그 안의 요소에 대한 매모리값은 고려되지 않아, 리스트 안에 리스트가 있는 경우 등 mutable(가변형) 자료형 안에 mutable 자료가 들어있는 경우 내부 자료의 주소값이 동일하다.

a = [[1,2], [3,4]]
b = a[:]
print(id(a))   # 4395624328
print(id(b))   # 4396179592
print(id(a[0]))   # 4396116040
print(id(b[0]))   # 4396116040

print(a)   # [[1,2], [3,4]]
print(b)   # [[1,2], [3,4]]
a[0][0] = 9
print(a)   # [[9,2], [3,4]]
print(b)   # [[9,2], [3,4]]

copy.deepcopy() 메서드를 활용해 깊은 복사를 할 수 있다.

상속

  • 클래스의 기능을 그대로 가져올 수 있다. (부모의 기능 + 상속 클래스 기능 추가 가능)
class Car:
   	def drive(self):
       	print('GO')

class Carr(Car):
  	def back(self):
       	print('BACK')
    
car1 = Carr()
car1.drive()   # GO

생성사 __init__() 메서드와 super()

  • 상속받는 child class는 기본적으로 parent class의 생성자를 호출하지 않는다.
  • 강제로 parent class의 생성자를 호출하거나, super() 메서드를 사용해 parent class의 생성자를 호출할 수 있다.
    • P_Class의 생성자를 직접 호출할 땐 self를 써야 하고, 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(20, 30)  # [C_Class] __init__() called!, [P_Class] __init__() called!'

0개의 댓글