본문 바로가기
언어/Python

[유튜브 나도코딩 1분파이썬] 100분완성 강의 요약본 #52강~62강(완강)

by 바다의 공간 2024. 5. 19.

[52강. 메소드 ]

클래스는 변수(name, resolution, price, color등)을 가질수도있지만 기능을 하는 함수(def event())도 가질 수 있습니다.

전 강의에서 이미 객체가 생성될 때 자동으로 호출되는 __init__함수를 사용해봤습니다.

이렇게 클래스 내에서 선언되는 함수를 메소드(Method)라고 합니다.

 


<블랙박스에서 여행모드를 켜고 싶을때 :: 평소에 하는 녹화는 시간이 지나면 덮어쓰기가 되고 여행모드는 별도의 폴더로 관리가 되게끔 해야함>

이렇게 되는건 변수가 아니라 기능의 영역이고 클래스는 기능을 가질 수 있다고 했으니까 BlackBox에 이 기능을 정의하도록 하겠습니다.


class BlackBox:

    def __init__(self, name, price):  

         self.name = name

         self.price = price

# __init__메소드 밑에 def를 통해서 하나 더 추가해주면 끝이다.

   def set_travel_mode(self): #이때 전달받는 값이 없으면 그냥 self만 적어주면 됩니다.

       print('여행모드 ON')

 

b1 = BlackBox('까망이',200000)

b1.set_travel_mode() #멤버변수 접근하듯이 점(.)을 이용해서 적어준다.

>>실행결과 : 여행모드 ON



   def set_travel_mode(self, min): #전달받는 값이 여행모드시간(분)

       print(str(min) + '분 동안 여행모드 ON')

 

b1 = BlackBox('까망이',200000)

b1.set_travel_mode(20)

>> 실행결과 : 20분 동안 여행모드 ON 


[53. self]

>>> 객체 자기 자신을 의미합니다.<<

1. 메소드를 정의할 때 처음 전달값은 반드시 self

2. 메소드 내에서는 self.name과 같은 형태로 멤버변수를 사용

<self 쩜!이 중요함>

 


클래스 내에서 메소드를 정의 할 때 self라는걸 썼었습니다.

보통 함수를 정의할때 전달값이 2개면 그 함수를 호출할때에도 전달값이 두개여야하는데

예) 

def add(num1, num2):  #전달값 2개

add(1, 2): #전달값 2개 #함수호출

클래스의 메소드는 self를 포함해서 전달값이 2개라고 해도 호출할 때는 self를 제외하고 나머지 1개에 대해서만 전달했었습니다.

예)

class BlackBox:

    def set_travel(self, min):  #전달값1:self #전달값2:min

 

b1.ser_travel_mode(20) #메소드 호출 # 전달값 1개  

 

예를들어

class BlackBox:

    def __init__(self, name, price):  

         self.name = name

         self.price = price

 

  def set_travel_mode(self, min):

       print(f'{self.name} {min}분 동안 여행모드 ON')

#self.name을 통해서 이 객체의 name이라는 멤버변수를 출력하는 건데 self는 객체 자기 자신입니다.

 

그래서 b1, b2라는  두 개의 객체가 만들어져 있을 때 메소드를 호출해보면 각 개체의 name 멤버변수를 포함한 출력결과를 볼 수 있습니다.

b1 = BlackBox('까망이', 200000)

b2 = BlackBox('하양이', 100000)

 

b1.set_travel_mode(20) >>결과 : 까망이 20분동안 여행모드 on

b2.set_travel_mode(10)>>결과 :  하양이 10분동안 여행모드 on

 

즉! 위 문장에서 b1.set_travel_mode(20) 보면 self부분에 b1객체가 들어가게 되고

b2는 b2객체 자기 자신이 들어가게 됩니다.

 

여기서 헷갈리다면! 이 문장을 잘 보세요.

BlackBox.set_travel_mode(b1, 20)

>>

BlackBox 클래스의 이름을 직접 적고 set_travel_mode메서드를 호출합니다. 

그리고 첫 번째 전달 값으로 b1을 넣고 두 번째 전달값으로 20을 넣으면 마치 함수로 호출하는것처럼

b1은 self로 20은 min으로 들어가게 됩니다.

 

 

아래 1번코드와 2번코드의 실행값은 같습니다.

 

b1.set_travel_mode(20) #1번코드

> 결과 : 까망이 20분동안 여행모드ON

 

BlackBox.set_travel_mode(b1, 20) #2번코드

> 결과 : 까망이 20분동안 여행모드ON

 

결국 우리는 BlackBox클래스의 메소드를 직접 호출하고 객체와 전달값을 지정해도 되지만

보다 간편하게 b1객체를 통해서 메소드를 호출하되 이미 b1객체라는걸 알고있으니까

self는 제외하고 나머지 전달값들만 지정해주면 된다는것으로 이해하면 됩니다.


[54. 상속]

이렇게 클래스들의 규모가 조금만 커져도 이렇게 중복되는 코드들이 많아질 수 있습니다.

새로운 클래스를 만들때마다 중복되는 내용들을  다시 다 적는다는 건 비효율적이죠

그렇지만 클래스에는 상속이라는것이 있습니다.

 

이렇게 상속받은 클래스에 내가 새로 짠 코드들을 확장하는 개념으로 쓰일 수 있습니다.

다시 돌아와서 보면 기본 블랙박스와 여행모드지원 블랙박스에는 모두 동일한 __init__()메소드를 가지고 있습니다.

거기에 여행모드 지원 블랙박스에는 set_travel_mode라는 메소드가 확장된 상태입니다.

이런 경우에는

calss TravelBlackBox(BlackBox): 

를 사용하면

BlackBox 클래스의 모든것을 그대로 물려받아서 갖다쓴다는 의미가 됩니다.

즉!

 

이랬던 코드가 

BlackBox 클래스로부터 모든것을 상속받아서 __init__()메소드를 기존 블랙박스의 것을 갖다 쓰면되니까

def __init__(self,name,price)

   self.name=name

   self.price=price

부분을 없애고

이렇게 바뀔 수 있습니다.

이때 왼쪽에 있는 클래스를 <<부모클래스>> 상속받은 오른쪽 클래스는  <<자식 클래스>> 라고 합니다.

코드 사용법은 동일합니다.

BlackBox 클래스를 통해서 b1 객체를 만드는 것처럼 TravelBlackBox를 이용해서 b2 객체를 만들면 됩니다.

b1 = BlackBox('까망이', 200000)

b2 = TravelBlackBox('하양이', 100000)

그러면 객체가 만들어질 때 상속을 받은 블랙박스의 __init__()메소드를 통해서 '하양이'와 '100000'원이 각각 

name과 price라는 멤버변수로 설정되는겁니다.

그리고 b1객체는 사용할수 없는 set_travel_mode()메소드를 b2객체에는 사용 할 수 있게 되는거죠


 

[55. super]

위에서 여행모드지원 블랙박스에 sd카드 기가로 옵션을 추가하려고 합니다.

그러려면 저장공간인 sd카드를 의미하는 sd를 추가해서  __init__()메소드를 새롭게 정의해줍니다.

앞에서 우리는 기본 블랙박스로부터 상속을 받아서 __init__()메소드를 생략할 수 있었는데 

다시 생겨버렸어요...

우리는 상속을 이용해서 부모클래스의 모든것을 이용하고 추가로 필요한 것에 대해서는 확장을 할 수 있다고

배웠습니다. 그러면 여기에서도 부모 클래스의 모든 것을 이용해야겠죠?

 

 

 

부모클래스에서는 name과

price를 받아서  멤버변수를 정의해주고 있습니다.

 

 

 

 

 

 

 

 

 

 

여행모드 지원 블랙박스에서는 

추가로 sd카드 데이터만 정의해주고

있습니다.

그러면 최소한 name과 

price를 설정하는 부분은 

기본 블랙박스인것을 사용해주는것이

좋겠죠?

 

 

 

 

 

 

 

 

그럴때는 이렇게 해줄 수 있습니다.

상속받은 BlackBox 클래스의 __init__()메소드를 직접 호출하면서 self를 명시하고

전달값으로 name과 price를 넘긴겁니다.

그러면 최소한 name과 price는 BlackBox의 __init__() 메소드를 이용해서 멤버변수로 설정을 하고

여기에서는 sd카드 부분에 대해서만 추가로 정의해주면 되겠죠?

 

그렇지만 보통 자식된 입장에서 엄마,아빠라고 부르지 ~~님 이라고 부르진 않죠? 상속도 같습니다.

부모클래스의 어떤 메소드를 호출 하고자 할 때! 부모 클래스의 이름을 그대로 적고 메소드를 그대로 호출 할 수도 있지만

예) 부모클래스 BlackBox.메소드(self, ...)

super()라는 것을 이용해서 메소드를 호출 할 수도 있어요.

이때 super()는 바로 부모 클래스를 의미하는 것입니다.

여기서 주의해야 할 점은 super에는 이렇게 괄호로 감싸줘야 한다는 부분입니다.

그리고 메소드의 전달값으로 self는 필요가 없다는 점 주의해주세요

 

그래서 여행모드지원 블랙박스의 경우에는 

이렇게 super을 이용해서 변경할 수 있습니다.


 

[56. 다중상속]

말 그대로 다양한 곳에서 상속받는 것을 다중상속이라고 합니다.

사용방법은 그냥 클래스명 ,(콤마)로 구분해서 적어주면 됩니다.

 

이 부분을 활용해보려고 했는데 이미 BalckBox에서 상속을 받고 있습니다. 다른 부분에서도 상속받고싶을 때는 어떻게 해야할까요?

이렇게 작성해볼 수 있습니다.

 

참고로 sd카드의 용량인 64gb를 의미합니다.

그러면 우리는 TravelBlackBox를 통해 b1객체를 만들고 나서 b1.make()메소드를 호출해보면 아래처럼 됩니다.

그런데 여기에 기능을 하나 더 추가로 하려고 합니다.

이번 기능은 이렇게 만들어진 영상을 메일로 바로 전송하는것입니다.

 

 

이 클래스의 이름은 

MailSender입니다. 구현클래스는 왼쪽처럼

생겼습니다.

 

send()메소드를 호출하면 메일 발송이 됩니다.

 

 

 

 

다중상속을 위해서 VideoMaker 뒤에 , 콤마를 입력하고 MailSender를 넣어줍니다.

그러면 이렇게 b1객체를 만들고 make()메소드를 통해서 추억용여행영상을 제작하고 나서

MailSender 클래스의  send()메소드를 호출해서 메일발송까지 쉽게 할 수 있게 되는거죠

 

이렇게 3개의 클래스로부터 다중상속을 받고 있는 형태가 됩니다.


[57. 메소드 오버라이딩]

부모 클래스의메소드를 자식 클래스에서 새롭게 정의하여 기존 동작을 개선하거나 새로운 동작을 수행하도록 하는것

위 코드는 개선된 버전의 여행모드를 지원하는 블랙박스인 AdvancedTravelBlackBox를 만들기로 합니다.

1. 여행모드일때의 기능을 확정해서 쓰는거니까 TravelBlackBox를 그대로 상속 받아서 쓰면 됩니다.

2. 그런데 set_travel_mode()메소드가 호출되었을때 단순히 여행 모드만 설정하는게 아니라 영상제작과 메일발송까지 해야하게 됩니다. 이때는 부모클래스의 set_travel_mode의 메소드를 AdvancedTravelBlackBox클래스 내에서 다시 정의할 수 있습니다.

즉 이렇게 자식클래스 내에서 똑같은 이름의 set_travel_mode() 메소드를 정의한 뒤에 여기안에서 

make메소드와 send메소드를 통해서 영상제작 및 메일발송까지 할 수 있습니다.

이렇게 하게되면 부모클래스인 TravelBlackBox의 set_travel_mode()메소드를 자식클래스에서 정의된 이 메소드로 

덮어쓰게 되는겁니다.

 

즉 자식클래스에서 새롭게 정의하지 않으면 부모클래스의 메소드를 쓰게되고

자식 클래스에서 같은 메소드를 새로 정의하면? 자식 클래스의 메소드를 새로 정의하면 

자식 클래스의 메소드를 사용하게 됩니다..

그러면 TravelBlackBox 클래스로부터 만들어진 b1객체를 가지고 set_travel_mode()메소드를 호출하면 

위와 같은 결과를

AdvancedTravelBlackBox 클래스를 통해 만들어진 b2객체를 가지고 set_travel_mode()메서드를 호출하면

메소드 오버라이딩을 통해서 영상제작과 메일발송까지의 동작을 포함하는 코드를 수행하게 되는겁니다.


 

[58. pass]

나중에 할테니 일단은 내버려 둬 라는 의미로 쓰입니다. 

클래스의 뼈대를 먼저 구성하고 자세한 메소드는 추후에 구성해도 됩니다.

이렇게 하게되면 일단은 완성된 코드로 되기때문에 format 메소드를 호출해도 에러가 발생되지 않습니다

 

pass의 사용?

1. 클래스

2. for, while,if, 함수에서도 사용 ㅎ가능합니다.

단, pass는 if의 조건문에서 사용은 불가능합니다.


[59.예외처리]

수행문장에서 에러가 발생했을 때 프로그램이 멈추지 않고 계속해서 수행될 수 있도록 에러를 처리하는 것을 말한다.

예외처리
try:
  수행문장
에.러가 발생할 가능성이 있는 문장
try: 을 입력하고 나서  다음 줄에 들여쓰리릏 하고 나서  수행할 문장들을 원하는 만큼 적어주시면 됩니다.
except:
  에러 발생 시 수행 문장
앞에 문장을 수행하다가 에러발생하면 수행할 문장을 적어주면 됩니다
**에러가 나지 않으면 수행되지 않음
else:
  정상 동작 시 수행 문장
try위치에 있는 문장들이 아무문제없이 잘 동작했을때 수행되는 문장입니다
finally:
  마지막으로 수행할 문장
try영역에 있는 문장들이 수행되다가 에러가 발생 하거나 말거나 상관없이 항상 마지막에 발생되는 문장입니다.

 

 

[1]

에러가 발생하면 에러처리를 하게됩니다

try:는 반드시 except: 또는 finally:구문과 함께 쌍을 이뤄야 합니다.

 

[2]

에러가 발생하면 에러처리 없이 마지막 문장을 수행하게 됩니다.

try:는 반드시 except: 또는 finally:구문과 함께 쌍을 이뤄야 합니다.

 

[3]

에러가 발생하면 에러처리를, 에러가 발생하지 않으면 정상 동작에 따른 처리를 하게 됩니다.

 

[4]

[3]번에 더해서 에러가 발생하거나 말거나 마지막 문장을 수행하고 마치게 됩니다.

 

 


[60.에러]

어떤 에러가 발생했는지 확인하는 방법

이렇게 except와 :(콜론)사이에 Exception as err 를 적어주고 프린트를 통해 err을 출력해보면 확인할 수 있습니다.

여기서 Exception은 모든 에러의 기본이 되는 클래스라서 그냥 이렇게 적으면 모든 에러에 대한 확인은 가능합니다만 

서로 다른상황에 따른 처리가 필요할 수 있습니다.

즉 에러 종류에 따라 서로 다른 처리를 하고자 할 때는 except 구문을 여러 개 적어서 그 에러에 해당하는 예외 처리를

해줄 수 있고 만약 앞에서 나열한 모든 에러에 해당하지 않는다면 최종적으로 Exception 을 통해서 처리를 해줄수도있습니다. 참고로 여기 err부분은 원하는 이름으로 써도 됩니다.


[61.모듈 ]

코드들이 작성되어있는 하나의 파이썬 파일을 의미합니다.(.py)

이 모듈에는 여태까지 공부한 변수, 함수, 클래스 등등이 정의되어 있을 수 있습니다.

새로운 환경에서 작업하다가 지난 프로젝트에 필요한것들이 있다면 가져다가 사용할 수 있습니다.

새로운 환경(파일)에서 지난 프로젝트(모듈)을 가져다 사용하기 위해서는 

(1)  import 모듈 <<임포트 띄어쓰기 모듈이름>>

(2) from 모듈 import 변수, 함수or클래스 <<from 띄우고 모듈명 띄우고 import 띄우고 변수,함수,클래스>>

 

 

간단한 모듈[1]

goodjob.py

 

def say():

    print('참 잘했어요')

 

여기서 1번방법으로 가져오는 방법입니다.

2번째 방법입니다.

 

1번과 2번의 차이점이 있습니다

1번은 import 모듈을 모두 가져와서 사용하겠다는것이고

2번은 모듈 중에서 필요한것들만 

우리 예제에서는 say()함수만 가져다쓰겠다는 의미가 됩니다.

 

모듈은 만들수도 있지만 이미 많은것들이 있습니다.

구글에서 list of python modules라고 검색을 해보면 자동으로 설치되는 것들을 확인할 수 있습니다.


 

 

[62.패키지 ]

모듈이 여러가지 모인것을 패키지라고 합니다.