클린코드와 디버깅(2일차)

이상우·2021년 8월 8일
0

첫째날, 강의 8시간을 듣고, 그것을 이해하기 위해 공부를 하는데 시간이 부족했다. 이어드림 시작전, 많은 각오를 하였는데 각오만큼 수업강도는 빡셌다. 그래도 같이 듣는 100명의 동료들이 실시간으로 디스코드에 질문을 하고, 이해한 누군가 답해주고. 이것을 지켜보는 것만으로도 힘이되고, 또다른 공부가 되었다. 2번째 날에는 디버깅에 대해 공부하였다. 아무리 뛰어난 개발자라도 처음부터 완벽한 코드를 짤 수는 없다. 오히려 오류가 없다면 그것을 의심하는 습관을 가져야 한다. 초보 개발자인 경우 오류를 만나면 당황하는 것이 기본이다. 나조차도 오류를 만나면 당황하였다. 코딩실력을 키우기 가장 좋은 방법은 오류를 많이 만나고, 그것을 해결하는 것이라고 한다. 이 강의를 통해서 앞으로 오류를 만나더라도 당황하지 않고, 현명하게 해결 할 수 있는 개발자가 될 것이다.

파이썬 예외(에러)의 종류

SytanxError:문법상 오류

파이썬 문법을 지키지 않았을 때 발생하는 에러. VS Code, PyCharm와 같은 IDE(통합개발환경)에서는 코딩을 할 경우 어느정도 문법을 자동으로 완성해주기 때문에 크게 걱정하기 않아도 된다. 하지만 정확하게 파이썬 문법을 알아야 할 필요가 있다.

NameError:참조변수 없음

예들 들어 변수a를 출력하려고 했는데, 코드 상에서 a를 선언한 적이 없다면 발생한느 에러다. a변수가 어떤 것을 정의하는지 지정해줘야 출력이 가능하다.

ZeroDivisionError:0으로 나눌 수 없음

수학에서도 분수에서 분모가 0일수는 없다. 파이썬에서도 0으로 나누면 에러가 난다.

IndexError:인덱스 범위 벗어남

예를 들어 a= [10, 20, 30]이라는 원소 3개를 가진 a리스트가 있다고 하자. 그런데 print(a[4])와 같이 4번째 원소를 호출하는 경우, a리스트에는 인덱스4인 원소가 없기에 IndexError가 일어난다.

ValueError:참조 값이 없음

예를 들어 a = [10, 20, 30] 이라는 원소 3개를 가진 리스트에서 a.remove(40)과 같이 40이라는 값을 가진 원소를 지우려고 하면 발생하는 애초에 그런 값이 없기 때문에 에러가 발생한다. ValueError: list.remove(x): x not in list 라고 그런 값이 리스트에 포함되어 있지 않다는 메시지가 뜬다. a.index(40)<-(원소가 40인 index가 무엇인가)라고 써도 마찬가지다.

KeyError:키 없음 에러(주로 딕셔너리 사용시)

mydict = {'Kim': 1, 'Lee': 2} 라는 딕셔너리가 있을 때 print(mydict['Park']) 라고 출력하면 발생하는 에러다. KeyError: 'Park' 라고 메시지가 뜬다.

이럴 땐 get 메소드를 활용하면 좋다. get 메소드는 dict.get(key, default=None)와 같이 해당하는 key값을 가진 Value를 반환하는 것이다.print(mydict.get('Park'))라고 써보면 None이 출력된다. 키가 없을 경우 None값이 반환되기도 하고, 그 뒤에 키가 없을 때 반환할 값을 지정해놓아도 된다. 이렇게 print(mydict.get('Park', 'unknown')) -> 'Park' 키 값을 가진 Value를 호출, 그런데 없을 겅우, unknown을 반환해라라는 뜻이다.

AttributeError:모듈, 클래스의 잘못된 속성 사용함

예를 들어 import time으로 time 모듈을 활용하고자 할 때 time.sleep() 이라고 하면 에러가 안 나지만, time.month() 라고 엉뚱한 함수를 사용하면 에러가 발생한다. AttributeError: module 'time' has no attribute 'month' 라고, time 모듈은 month라는 속성이 없다고 친절하게 알려준다.

FileNotFoundError:파일 못 찾음

예를 들어 어떤 텍스트 파일을 읽기 위해 f= open('ex.txt', 'r')이라고 쳤을 때, 해당 경로에 파일이 없다면 FileNotFoundError: [Errno 2] No such file or directory: 'ex.txt' 라는 메시지가 뜬다. 그런 파일이나 디렉토리(폴더)가 없다는 뜻이다.

TypeError:타입 안 맞음

a = [1,2] 라고 리스트를 만들어 놓고, b = “Hello” 라고 문자열을 만든 뒤 둘을 더하기로 연결해보자. print(a+b)라고 하면 TypeError: can only concatenate list (not "str") to list 라고 해서 리스트는 (문자열이 아닌) 리스트와 결합할 수 있습니다~ 라고 뜬다. 또 정수형(int)과 문자열(string)을 더하는 경우에도 발생한다.

ImportError:

improt하는 모듈이 없거나, 경로가 잘못설정되어있을경우 발생하는 에러.

RecursionError

Python이 정한 최대 재귀 깊이(1,000)보다 재귀의 깊이가 더 깊어질 때 발생하는 에러.

오류 예외 처리 기법

try, except문

try:
    ...
except [발생 오류[as 오류 메시지 변수]]:
    ...

try 블록 수행 중 오류가 발생하면 except 블록이 수행된다. 하지만 try 블록에서 오류가 발생하지 않는다면 except 블록은 수행되지 않는다. except 구문은 3가지 방법으로 사용할 수 있다.

1. try, except만 쓰는 방법

try:
    ...
except:
    ...

이 경우는 오류 종류에 상관없이 오류가 발생하면 except 블록을 수행한다.

2. 발생 오류만 포함한 except문

try:
    ...
except 발생 오류:
    ...

이 경우는 오류가 발생했을 때 except문에 미리 정해 놓은 오류 이름과 일치할 때만 except 블록을 수행한다는 뜻이다.

2-1.여러 오류를 포함한 except문

try:
    ...
except 발생 오류1:
   ... 
except 발생 오류2:
   ...

이 경우는 발생 오류가 발생했을 때, except1문에 미리 정해 놓은 오류 이름과 일치할 때만 excep1t 블록을 수행하고, 발생 오류2와 일치했을 때 except2 블록을 수행한다는 뜻이다.

3. 발생 오류와 오류 메세지 변수까지 포함한 except문

try:
    ...
except 발생 오류 as 오류 메시지 변수:
    ...

이 경우는 두 번째 경우에서 오류 메시지의 내용까지 알고 싶을 때 사용하는 방법이다.

try문에 else절 사용하기

try문에는 다음처럼 else절을 사용할 수 있다.

try:
    ...
except [발생 오류[as 오류 메시지 변수]]:
    ...
else:  # 오류가 없을 경우에만 수행된다.
    ...

try문 수행중 오류가 발생하면 except절이 수행되고 오류가 없으면 else절이 수행된다.

try문에 else절을 예

try:
    age=int(input('나이를 입력하세요: '))
except:
    print('입력이 정확하지 않습니다.')
else:
    if age <= 18:
        print('미성년자는 출입금지입니다.')
    else:
        print('환영합니다.')

만약 '나이를 입력하세요:' 라는 질문에 숫자가 아닌 다른 값을 입력하면 오류가 발생하여 '입력이 정확하지 않습니다.'라는 문장을 출력한다. 오류가 없을 경우에만 else절이 수행된다

오류 회피하기

프로그래밍을 하다 보면 특정 오류가 발생할 경우 그냥 통과시켜야 할 때가 있다.

try:
    f = open("나없는파일", 'r')
except FileNotFoundError:
    pass

위와 같이 try문 안에서 FileNotFoundError가 발생할 경우에 pass를 사용하여 오류를 그냥 지나칠 수 있다.

에러를 직접 일으키는 방법-raise

사용자가 직접 에러를 발생시키는 기능.
예시

def rsp(mine, yours):
    allowed = ['가위','바위', '보']
    if mine not in allowed:
        raise ValueError
    if yours not in allowed:
        raise ValueError
try:
    rsp('가위', '바')
except ValueError:
    print('잘못된 값을 넣었습니다!')

제대로 된 입력값을 넣지 않으면 ValueError를 발생시키고, ValueError시 "잘못된 값을 넣었습니다!"를 출력하도록 하였다.

가정설정문 assert

조건식이 True 일 경우에는 다음 명령어로 문제없이 진행되며, False일 경우 더 이상 프로그램이 실행되지 않고 "AssertionError"를 발생시키고 입력된 메세지를 출력한다. 메세지는 생략가능!

assert 조건, 메세지

assert는 if문처럼 단순히 에러를 찾는것이 아니라 완전히 값이 에러가 아니라는 것을 보증하기 위해 자주 사용된다.

느낀점

  • 어떤 오류 발생시, 구글링을 통해 해결하는 경험을 쌓을 필요가 있음
  • unittest를 정확하게 어떻게 사용하는지 연습할 필요가 있음

클린코딩


Clean Code(클린 코드) 애자일 소프트웨어 장인 정신
로버트 C. 마틴 지음 | 박재호 , 이해영 옮김 | 인사이트 | 2013년 12월 24일 출간

이번 강의에서는 클린코딩에 대해서 얇게 배웠다. 네이밍, 들여쓰기 제대로 하는 법, 주석 다는법 등 얇게 배웠다. 클린 코딩에 주 목적은 개발은 팀으로 이루어지기 때문에 다른사람들이 한눈에 쉽게 알아볼 수 있게(가독성), 유지보수성을 올리기 위해서다. 추후에 위에 책 "Clean Code"를 읽으면서 자세히 공부할 것이다. 책을 읽고, 이것에 대한 글을 자세하게 쓰도록 하겠다.

참고한 자료

http://hleecaster.com/python-exception/- 파이썬 에러 종류
https://wikidocs.net/30- 점프 투 파이썬/05-4예외 처리
https://wayhome25.github.io/python/2017/02/26/py-12-exception/-raise 사용법
https://responding.tistory.com/48 - raise

profile
구상한것을 구현할 수 있는 개발자가 되고 싶습니다.

0개의 댓글