{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "***\n", "# 23. 예외처리\n", "***\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "## 1 파이썬 예외의 종류\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 구문 에러 (Syntax Error)\n", " - 문법적 에러\n", " - 이클립스 등의 통합개발환경 도구에서는 자동으로 실행 전에 구문 에러를 체크 해 줌\n", " - 파이썬은 상대적으로 언어적 문법이 간단하기 때문에 구문 자체의 에러 발생 비율이 낮거나 다른 도구를 사용하여 완벽하게 제거할 수 있음\n", "\n", "- 예외 (Exception)\n", " - 구문 에러는 없으나 프로그램 실행 중 더 이상 진행 할 수 없는 상황" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-1 예외 발생 예제 보기\n", "- 예외 발생 예제 1: 정의되지 않은 변수 사용하기\n", " - NameError" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "ename": "NameError", "evalue": "name 'spam' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;36m4\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mspam\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'spam' is not defined" ] } ], "source": [ "4 + spam*3" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외 발생 예제 2: 0으로 숫자 나누기\n", " - ZeroDivisionError" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "integer division or modulo by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m10\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0ma\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mZeroDivisionError\u001b[0m: integer division or modulo by zero" ] } ], "source": [ "a = 10\n", "b = 0 \n", "c = a / b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- [note] 예외가 발생하면 프로그램은 바로 종료된다." ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false }, "outputs": [ { "ename": "ZeroDivisionError", "evalue": "float division by zero", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mZeroDivisionError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0;36m10.0\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0mdivision\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mdivision\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mdivision\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mn\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0;36m10.0\u001b[0m \u001b[0;34m/\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mdivision\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mZeroDivisionError\u001b[0m: float division by zero" ] } ], "source": [ "def division():\n", " for n in range(0, 5):\n", " print 10.0 / n\n", "\n", "division() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외 발생 예제 3: 문자열과 숫자 더하기\n", " - TypeError" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "ename": "TypeError", "evalue": "cannot concatenate 'str' and 'int' objects", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;34m'2'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: cannot concatenate 'str' and 'int' objects" ] } ], "source": [ "'2' + 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외 발생 예제 4: 참조 범위를 넘어서 인덱스 사용\n", " - IndexError" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "ename": "IndexError", "evalue": "list index out of range", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0ml\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mIndexError\u001b[0m: list index out of range" ] } ], "source": [ "l = [1, 2]\n", "print l[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외 발생 예제 5: 등록되지 않은 키로 사전 검색\n", " - KeyError" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "ename": "KeyError", "evalue": "'c'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0md\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m\"a\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"b\"\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'c'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mKeyError\u001b[0m: 'c'" ] } ], "source": [ "d = {\"a\": 1, \"b\": 2}\n", "print d['c']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외 발생 예제 6: 있지도 않은 파일을 열려고 할 때\n", " - IOError" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "ename": "IOError", "evalue": "[Errno 2] No such file or directory: 'aaa.txt'", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mIOError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0ma\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mopen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'aaa.txt'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mIOError\u001b[0m: [Errno 2] No such file or directory: 'aaa.txt'" ] } ], "source": [ "a = open('aaa.txt')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-2 내장 예외의 종류\n", "- 예외 클래스의 계층 구조 ([참고] https://docs.python.org/2/library/exceptions.html)\n", "
BaseException\n",
    " +-- SystemExit\n",
    " +-- KeyboardInterrupt\n",
    " +-- GeneratorExit\n",
    " +-- Exception\n",
    "      +-- StopIteration\n",
    "      +-- StandardError\n",
    "      |    +-- BufferError\n",
    "      |    +-- ArithmeticError\n",
    "      |    |    +-- FloatingPointError\n",
    "      |    |    +-- OverflowError\n",
    "      |    |    +-- ZeroDivisionError\n",
    "      |    +-- AssertionError\n",
    "      |    +-- AttributeError\n",
    "      |    +-- EnvironmentError\n",
    "      |    |    +-- IOError\n",
    "      |    |    +-- OSError\n",
    "      |    |         +-- WindowsError (Windows)\n",
    "      |    |         +-- VMSError (VMS)\n",
    "      |    +-- EOFError\n",
    "      |    +-- ImportError\n",
    "      |    +-- LookupError\n",
    "      |    |    +-- IndexError\n",
    "      |    |    +-- KeyError\n",
    "      |    +-- MemoryError\n",
    "      |    +-- NameError\n",
    "      |    |    +-- UnboundLocalError\n",
    "      |    +-- ReferenceError\n",
    "      |    +-- RuntimeError\n",
    "      |    |    +-- NotImplementedError\n",
    "      |    +-- SyntaxError\n",
    "      |    |    +-- IndentationError\n",
    "      |    |         +-- TabError\n",
    "      |    +-- SystemError\n",
    "      |    +-- TypeError\n",
    "      |    +-- ValueError\n",
    "      |         +-- UnicodeError\n",
    "      |              +-- UnicodeDecodeError\n",
    "      |              +-- UnicodeEncodeError\n",
    "      |              +-- UnicodeTranslateError\n",
    "      +-- Warning\n",
    "           +-- DeprecationWarning\n",
    "           +-- PendingDeprecationWarning\n",
    "           +-- RuntimeWarning\n",
    "           +-- SyntaxWarning\n",
    "           +-- UserWarning\n",
    "           +-- FutureWarning\n",
    "\t       +-- ImportWarning\n",
    "\t       +-- UnicodeWarning\n",
    "\t       +-- BytesWarning\n",
    "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "## 2 예외 처리 방법\n", "***" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1-1 try/except/else/finally 절 사용하기\n", "- 예외가 발생할 수 있는 상황을 예상하여 예외 발생 상황을 전체 코드 흐름을 함께 제어할 수 있다.\n", "- try/except/else/finally 절\n", " - 구문\n", "> try:
\n", ">     (예외 발생 가능한) 일반적인 수행문들
\n", "> except Exception:
\n", ">     예외가 발생하였을 때 수행되는 문들
\n", "> else:
\n", ">     예외가 발생하지 않았을 때 수행되는 문들
\n", "> finally:
\n", ">     예외 발생 유무와 관계없이 무조건 수행되는 문들
" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "zero division error!!!\n" ] } ], "source": [ "try:\n", " print 1.0 / 0.0\n", "except ZeroDivisionError:\n", " print 'zero division error!!!'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외 처리를 하면 예외 발생시 프로그램 종료가 되지 않는다." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "float division by zero\n", "10.0\n", "5.0\n", "3.33333333333\n", "2.5\n" ] } ], "source": [ "def division():\n", " for n in range(0, 5):\n", " try:\n", " print 10.0 / n\n", " except ZeroDivisionError, msg:\n", " print msg\n", "\n", "division()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- else: 구문은 except: 구문없이 사용 못한다. " ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "collapsed": false }, "outputs": [ { "ename": "SyntaxError", "evalue": "invalid syntax (, line 5)", "output_type": "error", "traceback": [ "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m5\u001b[0m\n\u001b[0;31m else:\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], "source": [ "def division():\n", " for n in range(0, 5):\n", " try:\n", " print 10.0 / n\n", " else:\n", " print \"Success\"\n", "\n", "division() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 상황에 따라서는 에러와 함께 따라오는 정보를 함께 받을 수도 있다." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error - name 'spam' is not defined\n" ] } ], "source": [ "try:\n", " spam()\n", "except NameError, msg:\n", " print 'Error -', msg" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error - name 'spam' is not defined\n" ] } ], "source": [ "try:\n", " spam()\n", "except NameError as msg:\n", " print 'Error -', msg" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- try 절 안에서 간접적으로 호출한 함수의 내부 예외도 처리할 수 있다." ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "zero division error!!! - integer division or modulo by zero\n" ] } ], "source": [ "def zero_division():\n", " x = 1 / 0\n", "\n", "try:\n", " zero_division()\n", "except ZeroDivisionError, msg:\n", " print 'zero division error!!! -', msg" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "zero division error!!! - integer division or modulo by zero\n" ] } ], "source": [ "def zero_division():\n", " x = 1 / 0\n", "\n", "try:\n", " zero_division()\n", "except ZeroDivisionError as msg:\n", " print 'zero division error!!! -', msg" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- except 뒤에 아무런 예외도 기술하지 않으면 모든 예외에 대해 처리된다." ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error\n" ] } ], "source": [ "try:\n", " spam()\n", " print 1.0 / 0.0\n", "except:\n", " print 'Error'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 여러 예외들 각각에 대해 except 절을 다중으로 삽입할 수 있다." ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ZeroDivisionError !!!\n", "Exit !!!\n" ] } ], "source": [ "b = 0.0\n", "name = 'aaa.txt'\n", "try:\n", " print 1.0 / b\n", " spam()\n", " f = open(name, 'r')\n", " '2' + 2\n", "except NameError:\n", " print 'NameError !!!'\n", "except ZeroDivisionError:\n", " print 'ZeroDivisionError !!!'\n", "except (TypeError, IOError):\n", " print 'TypeError or IOError !!!'\n", "else:\n", " print 'No Exception !!!'\n", "finally:\n", " print 'Exit !!!'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 파일에서 숫자를 읽어와서 읽은 숫자로 나누기를 하는 예제\n", " - 꼼꼼한 예외 처리 예제" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "/Users/yhhan/git/python-e-learning\n", "1.0\n", "Finally!!!\n" ] } ], "source": [ "import os\n", "print os.getcwd()\n", "filename = 't.txt'\n", "\n", "try:\n", " f = open(filename, 'r')\n", "except IOError, msg:\n", " print msg\n", "else:\n", " a = float(f.readline())\n", " try:\n", " answer = 1.0 / a\n", " except ZeroDivisionError, msg:\n", " print msg\n", " else:\n", " print answer\n", " finally:\n", " print \"Finally!!!\"\n", " f.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2-2 같은 부류의 예외 다 잡아내기\n", "- 예외 클래스들은 상속에 의한 계층 관계를 지니고 있기 때문에 이를 이용하면 여러 예외들을 한꺼번에 잡을 수 있다.\n", "- 예를 들어, ArithmeticError의 하위 클래스로서 FloatingPointError, OverflowError, ZeroDivisionError가 존재하기 때문에 이들 하위 클래스 예외가 발생하였을 경우 ArithmeticError로서 잡아낼 수 있다. " ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ArithmeticException occured\n" ] } ], "source": [ "def dosomething():\n", " a = 1/0\n", "\n", "try:\n", " dosomething()\n", "except ArithmeticError:\n", " print \"ArithmeticException occured\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외가 임의의 except에 의해 잡히면 다른 except에 의해서는 잡히지 않는다. " ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ZeroDivisionError occured\n" ] } ], "source": [ "def dosomething():\n", " a = 1/0\n", "\n", "try:\n", " dosomething()\n", "except ZeroDivisionError: # ZeroDivisionError는 이곳에서 잡힌다.\n", " print \"ZeroDivisionError occured\"\n", "except ArithmeticError: # FloatingPointError, OverflowError는 이곳에서 잡힌다.\n", " print \"ArithmeticException occured\"" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ArithmeticException occured\n" ] } ], "source": [ "def dosomething():\n", " a = 1/0\n", "\n", "try:\n", " dosomething()\n", "except ArithmeticError:\n", " print \"ArithmeticException occured\"\n", "except ZeroDivisionError: # 이곳에서 ZeroDivisionError는 잡히지 않는다. ==> 잘못된 코드\n", " print \"ZeroDivisionError occured\" " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***\n", "## 3 예외 발생\n", "***\n", "### 3-1 raise로 예외 발생하기" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 예외를 특정 상황 조건에서 raise 키워드를 통해 발생시킬 수 있다.\n", "- 아래 예는 시퀀스 형 클래스를 설계할 때 인덱싱을 구현하는 \\_\\_getitem\\_\\_ 메소드에서 인덱스가 범위를 넘을 때 IndexError를 발생시킨다." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4 16\n", "0 1 4 9 16 25 36 49 64 81" ] }, { "ename": "IndexError", "evalue": "", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# IndexError가 발생하는 시점까지 반복한다\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m \u001b[0;32mprint\u001b[0m \u001b[0ms\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;31m# 첨자 범위가 넘었다\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36m__getitem__\u001b[0;34m(self, k)\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__getitem__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mk\u001b[0m \u001b[0;34m>=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mn\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mk\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m0\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mIndexError\u001b[0m \u001b[0;31m# 첨자 범위를 벗어나면 IndexError 예외를 발생시킴\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 7\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mk\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mk\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__len__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mIndexError\u001b[0m: " ] } ], "source": [ "class SquareSeq:\n", " def __init__(self, n):\n", " self.n = n\n", " def __getitem__(self, k):\n", " if k >= self.n or k < 0 :\n", " raise IndexError # 첨자 범위를 벗어나면 IndexError 예외를 발생시킴\n", " return k * k\n", " def __len__(self):\n", " return self.n\n", " \n", "s = SquareSeq(10)\n", "print s[2], s[4]\n", "for x in s: # IndexError가 발생하는 시점까지 반복한다\n", " print x,\n", "print s[20] # 첨자 범위가 넘었다" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3-2 사용자 클래스 예외 정의 및 발생시키기\n", "- 사용자 정의 예외 클래스를 구현하는 일반적인 방법은 Exception 클래스를 상속 받아 구현한다.\n", " - Exception 클래스의 서브 클래스 중 하나를 상속 받아도 된다.\n", "- 사용자 정의 예외 발생 방법\n", " - 내장 예외 발생 방법과 동일하게 raise [클래스의 인스턴스] 와 같이 해당 예외 클래스의 인스턴스를 던진다.\n", "- 사용자 정의 예외를 잡는 방법\n", " - except [클래스 이름] 과 같이 해당 예외 클래스 이름을 사용한다.\n", "- 아래 예에서 except Big이 잡는 예외는 Big과 Small 이다.\n", " - 이유: Small은 Big의 하위 클래스이기 때문" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Exception occurs!\n", "Exception occurs!\n" ] } ], "source": [ "class Big(Exception):\n", " pass\n", "\n", "class Small(Big):\n", " pass\n", "\n", "def dosomething1():\n", " x = Big()\n", " raise x\n", " \n", "def dosomething2():\n", " raise Small()\n", " \n", "for f in (dosomething1, dosomething2):\n", " try:\n", " f()\n", " except Big:\n", " print \"Exception occurs!\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 3-3 예외값 전달하기 \n", "- raise 키워드 뒤에 예외와 함께, 추가 메시지를 함께 던질 수 있다." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "message!!!\n" ] } ], "source": [ "def f():\n", " raise Exception, 'message!!!'\n", " \n", "try:\n", " f()\n", "except Exception, a:\n", " print a" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- 생성자 안에 넣어준 에러 메시지는 except 키워드 사용시에 두 번째 인자로 해당 메시지를 받을 수 있다." ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0으로 나누고 있습니다.\n" ] } ], "source": [ "a = 10\n", "b = 0\n", "try:\n", " if b == 0:\n", " raise ArithmeticError('0으로 나누고 있습니다.')\n", " a / b\n", "except ArithmeticError, v:\n", " print v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

참고 문헌: 파이썬(열혈강의)(개정판 VER.2), 이강성, FreeLec, 2005년 8월 29일

" ] } ], "metadata": {}, "nbformat": 4, "nbformat_minor": 0 }