[제로베이스_데이터 취업 스쿨 16기] 5일차(6/7 ~ 8)

jumee·2023년 6월 8일
0
post-thumbnail

0. 클래스

class 키워드와 속성(변수), 기능(함수)를 이용해서 클래스를 구현할 수 있다.

예시 코드

  1. 차 기능, 속성을 가지는 클래스 만들기
class Car:
    def __init__(self,col,len):
        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}')


# 생성자 호출 : Car()
car1 = Car('red',200)
car2 = Car('blue',300)


car1.printCarInfo()
car2.printCarInfo()

car1.doStop()
car1.doStart()
  1. 비행기 기능(착륙/이륙)과 속성(길이,무게,색상)을 가지는 클래스를 만들어보고, 5개의 객체를 만들어보자.
class Airplane:
    def __init__(self,col,len, wt):
        self.color = col
        self.length = len
				self.weight = wt

    def doLand(self):
        print('착륙합니다.')


    def doDepart(self):
        print('이륙합니다.')


    def printAirInfo(self):
        print(f'self.color: {self.color}')
        print(f'self.length: {self.length}')
        print(f'self.weight: {self.weight}')


air1 = Airplane('red',72,120000)
air2 = Airplane('blue',80,160000)
air3 = Airplane('white',77,130000)
air4 = Airplane('wine',88,180000)
air5 = Airplane('yellow',73,125000)

정의된 객체의 속성은 변경할 수도 있다.

class Airplane:
    def __init__(self,col,len, wt):
        self.color = col
        self.length = len
				self.weight = wt

    def doLand(self):
        print('착륙합니다.')


    def doDepart(self):
        print('이륙합니다.')


    def printAirInfo(self):
        print(f'self.color: {self.color}')
        print(f'self.length: {self.length}')
        print(f'self.weight: {self.weight}')


air1 = Airplane('red',72,120000)

# air1의 객체 속성 변경
air1.color = 'purple'
air1.length = 75
air.weight = 130000

air.printAirInfo() # -> 변경된 정보를 확인할 수 있다.  

1. 객체

1-1. 얕은 복사와 깊은 복사

얕은 복사는 객체 주소를 복사하는 것, 객체 자체가 하나 더 생기는 것이 아니다.

깊은 복사는 기존의 객체 자체를 하나 더 복사하는 것이다.

[ 얕은 복사 ]

아래 식처럼 사용할 경우, 얕은 복사가 된다.

tc1 = TemCls(10,'hello')
tc2 = tc1

얕은 복사는 tc2의 속성을 변경시키면 tc1의 속성도 함께 변경된다.

[ 깊은 복사 ]

깊은 복사를 구현하는 방식은 여러가지가 있다.

  1. copy 모듈 사용하기
import copy

tc1 = TemCls(10,'hello')
tc2 = copy.copy(tc1) # tc1가 가리키는 객체와 tc2가 가리키는 객체가 달라지게 된다.

깊은 복사는 tc2의 속성을 변경시켜도 tc1의 값에 영향을 주지 않는다.

  1. 리스트에서의 복사 활용하기
    리스트에서는 기본적으로 id() 라는 함수로 객체의 메모리 주소를 확인할 수 있다.

    2-1. 얕은 복사
    # 얕은 복사
    scores = [9,8,7,6,5,4]
    copyScores = scores
    
    print(f'id(scores): {id(scores)}')
    print(f'id(copyScores): {id(copyScores)}')
    
    #id(scores): 4333407680
    #id(copyScores): 4333407680
    2-2. 깊은 복사
      # 깊은 복사
    # 1. for 구문, append()
    copyScores = []
    for s in scores:
       copyScores.append(s)
    
    print(f'id(scores): {id(scores)}')
    print(f'id(copyScores): {id(copyScores)}')
    
    #id(scores): 4376186432
    #id(copyScores): 4376307584
   
```python
----------------------------------------------------------

# 2. extend() 
copyScores.extend(scores)

print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')

#id(scores): 4336315968
#id(copyScores): 4336690688

------------------------------------------------------------

# 3. copy() : 리스트 내장 깊은 복사 함수
copyScores = scores.copy()

print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')

#id(scores): 4338250176
#id(copyScores): 4338250304

------------------------------------------------------------

# 4. 슬라이싱 : [:]
copyScores = scores[:]

print(f'id(scores): {id(scores)}')
print(f'id(copyScores): {id(copyScores)}')

#id(scores): 4368101760
#id(copyScores): 4368101888

2. 클래스 상속

클래스는 또 다른 클래스를 상속해서 안에 있는 기능들을 사용할 수 있다.

class First:
	
	def go(self):
		print(f'[First] go() called!')

	def back(self):
		print(f'[First] back() called!')	


class Second(First): # 클래스 상속

	def second(self):
		print(f'[Second] go() called!')


mySecond = Second()
mySecond.second()
mySecond.go()
mySecond.back()


#[Second] go() called!
#[First] go() called!
#[First] back() called!

예시 코드

  1. 덧셈, 뺄셈 기능이 있는 클래스를 만들고, 이를 상속하는 클래스를 만들어서 곱셈과 나눗셈 기능을 추가해보자.
class AddSub:

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

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

class MulDiv(AddSub):
	
	def mul(self,n1,n2):
		return n1 * n2

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

cal = MulDiv()

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

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



cal = Calculator() # 객체 생성 및 생성자 호출

# [Calculator] __init__() called!
  • init 의 역할
    : 속성을 초기화해준다.
    < 외부에서 매개변수로 값을 받아오는 방식>

    class Calculator():
    		def __init__(self,n1,n2):
    			print(f'[Calculator] __init__() called!')
    			self.num1 = n1
    			self.num2 = n2
    
    cal = Calculator(10,20) # 객체 생성 및 생성자 호출
    print(cal.num1)
    print(cal.num2)

    < 내부에서 값을 고정시키는 방식>

    class Calculator():
    
    		def __init__(self):
    			print(f'[Calculator] __init__() called!')
    			self.num1 = 10
    			self.num2 = 100
    	
    cal = Calculator()
    print(cal.num1)
    print(cal.num2)

    < 혼합 >

    class Calculator():
    
    		def __init__(self,n):
    			print(f'[Calculator] __init__() called!')
    			self.num1 = n
    			self.num2 = 100
    
    cal = Calculator(3.14) # 객체 생성 및 생성자 호출
    print(cal.num1)
    print(cal.num2)
  • 상위 클래스 속성 초기화하기 - super()
    부모 - 자식 클래스 간 상속이 되어 있을 경우, 기능은 특별한 조건 없이 사용할 수 있지만, 속성의 경우에는 부모 속성을 사용하고 싶다면 super() 메소드를 넣어줘야 한다.

class Parent():

	def __init__(self,pnum1,pnum2):
		print(f'[Pclass] __init__() called!')
		self.pnum1 = pnum1
		self.pnum2 = pnum2



class Child():

	def __init__(self,cnum1,cnum2):
		print(f'[Cclass] __init__() called!')

		# 부모 클래스 init 호출하여 속성값 초기화해주기
		super().__init__(cnum1,cnum2)
		
		self.cnum1 = cnum1
		self.cnum2 = cnum2


cls = Child(10,20)


# [Cclass] __init__() called!
#[Pclass] __init__() called!
  • 다중 상속 - 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()


#drive() method called! 
#turbo() method called!
#fly() method called!

오버라이딩 : 메서드를 재정의하다

두 클래스가 종속관계에 있을 때, 하위 클래스가 상위 클래스의 메서드를 재정의하게 되는 경우를 의미한다.

[예시]

class Robot:

    def __init__(self,c,h,w):
        self.color = c
        self.height = h
        self.weight = w

    def fire(self):
        print(f'미사일 발사!')


    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()

추상클래스

상위 클래스에서 하위 클래스에 메서드 구현을 강요하는 방법을 일컫는다

추상 클래스의 활용 기능은 상위 클래스에서 선언만 해준 메서드를 서로 다른 하위 클래스에서 입맛에 맞게 변경할 수 있다는데 있다.

추상클래스를 구현하는데 필요한 모듈은 abc 안의 ABCMeta, abstractmethod 함수다.

[예시]

#################### 1 #####################
from abc import ABCMeta
from abc import abstractmethod

class AirPlane(metaclass=ABCMeta):

    @abstractmethod
    def flight(self): 
        pass # 구현되지 않은 메소드

    def forward(self):
        print('전진!')

    def backward(self):
        print('후진!')


class Airliner(AirPlane):

    def __init__(self,c):
        self.color = c

    def flight(self):
        print('시속 400km/h 비행!')



al = Airliner('red')
al.flight()
al.forward()
al.backward()
#################### 2 #####################
# 계산기 추상 클래스 -> 새로운 계산기 클래스를 생성하기
# 덧셈 , 뺄셈, 곱셈, 나눗셈 기능이 있어야 함
from abc import ABCMeta
from abc import abstractmethod

class Calculator(metaclass=ABCMeta):

    @abstractmethod
    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 Newcalculator(Calculator):


    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


value = Newcalculator()
print(value.add(10,20))
print(value.sub(10,20))
print(value.mul(10,20))
print(value.div(10,20))

여기까지 객체지향 프로그래밍의 개념과 클래스 개념, 활용 방법들을 살펴봤다. 다음 포스팅은 try ~ except 예외 처리 구문 및 활용 방법들에 대해서 정리해볼 예정이다.

try ~ except 예외처리 개념 및 활용 🔜

profile
공부한 내용들에 대해 끄적이는 공간입니다💎

0개의 댓글