Chapter 7 Exceptions and Assertions

<目次>


例外発生の例

# 例1: IndexError
>>> test = [1, 2, 3]
>>> test[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Chapter 7.1, Handling Exceptions (例外を扱おう)

# 例2-1: num_failuresが0の時、ZeroDivisionErrorになる。
def calc_ratio(num_success, num_failures):
    success_failure_ratio = num_success / float(num_failures)
    print('success_failure_ratio = {0}'.format(success_failure_ratio))
    print('Now here')
 
calc_ratio(5, 1)
# -> success_failure_ratio = 5.0
# -> Now here
 
calc_ratio(5, 0)
# -> ZeroDivisionError: float division by zero
# 例2-2: num_failuresが0の時、異なるコードを実行させる。
def calc_ratio2(num_success, num_failures):
    try:
        success_failure_ratio = num_success / float(num_failures)
        print('success_failure_ratio = {0}'.format(success_failure_ratio))
    except ZeroDivisionError:
        print('失敗回数0のため、success/failuer比は定義できません。')
    print('Now here')
 
calc_ratio(5, 1)
# -> success_failure_ratio = 5.0
# -> Now here
 
calc_ratio(5, 0)
# -> 失敗回数0のため、success/failuer比は定義できません。
# -> Now here
# exceptブロックの記述例
try:
    #tryブロック
except (ValueError, TypeError):
    #tryブロック処理中に、
    #ValueErrorかTypeErrorが起きた場合に処理されるexceptブロック。
except:
    #tryブロック処理中に、
    #上記以外の例外が起きた場合に処理されるブロック。

polymorphicなコード

# 例3-1: 古典的な関数や手続き(単態性なコード)
def read_int():
    while True:
      val = input('Enter an integer: ')
      try:
          val = int(val)
          return val
      except ValueError:
          print('{0} is not an integer'.format(val))
 
data = read_int()
# -> Enter an integer: 123
print(data)
# -> 123
 
data = read_int()
# -> Enter an integer: hoge
# -> hoge is not an integer
# -> Enter an integer:
# 例3-2: 抽象度の高い関数や手続き(多態性なコード)
def read_val(val_type, request_msg, error_msg):
    while True:
        val = input(request_msg + ' ')
        try:
            val = val_type(val)
            return val
        except ValueError:
            print('{0} {1}'.format(val, error_msg))
 
data = read_val(int, '整数を入力下さい:', 'は整数ではありません!')
# -> 整数を入力下さい: 123
print(data)
# -> 123
 
data = read_val(float, '浮動小数点数を入力下さい:', 'は浮動小数点数ではありません!')
# -> 浮動小数点数を入力下さい: hoge
# -> hoge は浮動小数点数ではありません!
# -> 浮動小数点数を入力下さい: 1.234
print(data)
# -> 1.234

Chapter 7.2, Exceptions as a Control Flow Mechanism(フロー制御として利用される例外)

# 例4-1(教科書の図7.1): raiseによるエラー文生成。
def get_ratios(vect1, vect2):
    """Assumes: vect1 and vect2 are lists of equal length of numbers
    Returns: a list containing the meaningfulvalues of vect1[i]/vect2[i]
    """
    ratios = []
    for index in range(len(vect1)):
        try:
            ratios.append(vect1[index]/float(vect2[index]))
        except ZeroDivisionError:
            ratios.append(float('nan')) #nan = Not a Number
        except:
            raise ValueError('get_ratios() called with bad arguments.')
    return ratios
 
print(get_ratios([1.0, 2.0, 7.0], [1.0, 2.0, 0.0]))
# -> [1.0, 1.0, nan]
 
print(get_ratios([], []))
# -> []
 
print(get_ratios([1.0, 2.0], [3.0]))
# Traceback (most recent call last):
#   File "<stdin>", line 8, in get_ratios
# IndexError: list index out of range
#
# During handling of the above exception, another exception occurred:
#
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 12, in get_ratios
# ValueError: get_ratios() called with bad arguments.

Chapter 7.3, Assertions (アサーション)

# 例5: アサーションの例
def get_ratios2(vect1, vect2):
    """Assumes: vect1 and vect2 are lists of equal length of numbers
    Returns: a list containing the meaningfulvalues of vect1[i]/vect2[i]
    """
    assert len(vect1) == len(vect2), "vect1とvect2の要素数は揃えて下さい!"
    ratios = []
    for index in range(len(vect1)):
        try:
            ratios.append(vect1[index]/float(vect2[index]))
        except ZeroDivisionError:
            ratios.append(float('nan')) #nan = Not a Number
        except:
            raise ValueError('get_ratios() called with bad arguments.')
    return ratios
 
print(get_ratios2([1.0, 2.0, 7.0], [1.0, 2.0, 0.0]))
# -> [1.0, 1.0, nan]
 
print(get_ratios2([], []))
# -> []
 
print(get_ratios2([1.0, 2.0], [3.0]))
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "<stdin>", line 5, in get_ratios2
# AssertionError: vect1とvect2の要素数は揃えて下さい!

参考サイト