본문 바로가기

python tutorial -8 에러 / 예외

https://docs.python.org/ko/3/tutorial/errors.html


python tutorial part 8 

에러와 예외 エラーと例外

 

 


8.1. 문법 에러 構文エラー


SyntaxError


문법 에러

= 파싱 에러

가장 자주 만나는 에러


構文エラー構文解析エラー (parsing error) としてもられており

Python 勉強しているもよく遭遇する問題つでしょう:

 


>>> while True print('Hello world')
  File "<stdin>", line 1
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

-> 콜론 (':') 이 빠져있음


파서 - 문제 줄 출력

줄에서 에러가 감지된 가장 앞의 위치를 '화살표'로 표시

파일 이름과 줄 번호가 인쇄되어서입력이 스크립트로부터 올 때 찾을 수 있도록 합니다.

 

パーサは違反きている表示さな矢印表示して行中でエラーが検出された最初位置します

エラーは矢印直前の トークンでひきこされています (またはなくともそこで検出されています)

入力がスクリプトからている場合どこをればよいかかるようにファイル行番号出力されます

 

 

 


8.2. 예외 例外


문법적으로 바르더라도, 실행하면 에러가 뜰 수 있습니다.

실행 중에 감지되는 에러들을 예외 라고 부르고 무조건 치명적이지는 않습니다:


たとえ構文的しくても実行しようとしたときエラー発生するかもしれません

実行中検出されたエラー 例外 (exception) ばれ致命的とはりません

 

 

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly


 ZeroDivisionErrorNameErrorTypeError  


내장 예외

항상 참 / 사용자 정의 예외는 절대적은 아님

내장 식별자 (예약 키워드가 아닙니다).


エラーメッセージの最終行こったかをしています

例外々な(type) こりそのがエラーメッセージの一部として出力されます

でのZeroDivisionError, NameError, TypeError です


例外型として出力される文字列発生した例外です

これはての例外についてちますがユーザ定義例外では (つようにするのは有意義慣習ですが) ずしもちません

標準例外名前みの識別子です (予約語ではありません)

 


줄의 나머지 부분 

예외 형 / 원인 상세


りの例外詳細その例外きたかに依存します

 


에러 메시지의 앞부분 

: 스택 트레이스의 형태. 예외가 일어난 위치의 context를 보여줍니다

일반적으로 소스의 줄들을 나열하는 스택 트레이스를 포함하고 있습니다

하지만, 표준 입력에서 읽어 들인 줄들은 표시하지 않습니다.

 

エラーメッセージの先頭部分では

例外発生した実行コンテキスト (context) スタックのトレースバック (stack traceback) 形式しています

一般にはこの部分にはソースコードをリストしたトレースバックが表示されます

しかし標準入力からられたコードは表示されません

 



8.3. 예외 처리하기 例外処理する

 

선택한 예외를 처리하기


ex)

올바른 정수가 입력될 때까지 입력 요청

사용자 프로그램 인터럽트 허용 (Control-C 등); 사용자 인터럽트는 KeyboardInterrupt 예외 발생.


有効文字列入力されるまでユーザに入力しますが

ユーザがプログラムに (Control-C またはオペレーティングシステムがサポートしているらかのキーを使って) みをかけてプログラムを中断させることができるようにしています

ユーザが生成したみはKeyboardInterrupt 例外送出されることで通知されるということに注意してください

 

 

>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")
...



try

 

- try (try except 사이실행

- 예외 x) , except 절 을 건너뛰고 종료

- 예외 o) 남은 부분들을 건너뜁니다

except 매치 o -> except 절 실행. 다음 try 문 뒤로 이어집니다.

except 매치 x -> 외부 try 문으로 전달

해당 처리기가 발견되지 않으면, 처리되지 않은 예외. 메시지 출력 후 실행 멈춤


まずtry (try clause) (キーワード try except ) 実行されます


例外発生しなければexcept をスキップして try 実行えます


try 節内実行中例外発生するとそのりはばされます

例外型except キーワードの指定されている例外一致する場合

except 実行されたtry ろへ実行継続されます

もしも except 指定された例外一致しない例外発生するとその例外try 外側されます

例外するハンドラ (handler処理部) がどこにもなければ処理されない例外 (unhandled exception) となり上記したようなメッセージをして実行停止します

 


try문에 여러 except 절을 가질 수 있음.

하나의 처리기만 실행

try 절에서 발생한 예외만 처리

except 절 튜플로 여러 예외 지정 가능

 

つの try には複数except けられ々の例外するハンドラを指定できます

くともつのハンドラしか実行されません。 

ハンドラは対応する try 節内発生した例外だけを処理try 節内例外ハンドラできた例外処理しません。 

except では丸括弧ったタプルという複数例外指定できます

 

... except (RuntimeError, TypeError, NameError):
...     pass


except절은 예외와 같은 클래스이거나 부모 클래스일 때 매치됩니다

(하지만 다른 방식으로는 매치되지 않습니다 --- 자식 클래스를 나열한 except 절은 베이스 클래스와 매치되지 않습니다). 


except のクラスは

例外じクラスか基底クラスのときに互換 (compatible)となります。 

(逆方向ではちません --- 派生クラスの例外がリストされている except 基底クラスの例外互換ではありません)

えばのコードは、 

 

 

B, C, D 순서대로 인쇄

B, C, D 順序通りに出力します:

class B(Exception):
    pass

class C(B):
    pass

class D(C):
    pass

for cls in [B, C, D]:
    try:
        raise cls()
    except D:
        print("D")
    except C:
        print("C")
    except B:
        print("B")


except 절이 뒤집히면 (except B 가 처음에 오도록), B, B, B를 인쇄 - 처음으로 매치되는 절이 실행


except んでいた場合 (except B 最初にくる場合)B, B, B 出力されるはずだったことに注意してください --- 最初一致した except 駆動されるのです

 


마지막 except 절은 예외이름 생략가능

와일드카드 역할

극도의 주의 필요. - 이런 식으로 실제 프로그래밍 에러를 가리기 쉽기 때문입니다

에러 메시지를 인쇄한 후에 예외를 다시 일으키는데 사용될 수도 있습니다 (호출자도 예외를 처리할 수 있도록):


最後except では例外名いてワイルドカード (wildcard総称記号) にすることができますワイルドカードの except 非常注意して使ってくださいというのはワイルドカードは通常のプログラムエラーをたやすくしてしまうからですワイルドカードの except はエラーメッセージを出力した例外再送出する (関数やメソッドの同様にして例外処理できるようにする) 用途にも使えます:

 

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise




else

마지막 except 절 뒤에와야 함

try 절이 예외를 일으키지 않을 때 실행되어야만 하는 코드에 유용합니다. 예를 들어:


try ... except には

オプションで else (else clause) けることができます

else ける場合ての except よりもろにかなければなりません

else try 例外送出されなかったときに実行されるコードをくのに役立ちます


for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()


else 의 사용

try절 추가 보다 좋음. 

우연을 방지

 

 追加のコードをえるのは try よりも else がよいでしょう。 

なぜならそうすることで try ... except 保護されたコードから送出されたもの以外例外って捕捉してしまうという事態けられるからです

 

 

예외가 발생할 때

예외 인자 : 예외에 연관된 값

인자의 존재와 형은 예외 형에 의존적


例外発生するとき例外関連付けられたつことができます

この例外引数 (argument) ともばれます

引数有無および引数例外依存します

 


except 예외 명 뒤 변수를 지정가능

변수는 인자들이 instance.args 에 저장된 예외 인스턴스에 연결됩니다

편의를 위해, 예외 인스턴스는 __str__() 를 정의해서, .args를 참조하지 않고도 인자들을 직접 인쇄할 수 있습니다

예외를 일으키기 전에 인스턴스를 먼저 만들고 필요한 어트리뷰트들을 추가할 수도 있습니다.


except では例外名変数指定することができます

この変数例外インスタンスにけられておりinstance.args 例外インスタンス生成時引数っています

例外インスタンスには __str__() 定義されており.args 参照しなくても引数直接印字できるように利便性られています

必要なら例外送出するにインスタンスして任意属性追加できます


>>> try:
...     raise Exception('spam', 'eggs')
... except Exception as inst:
...     print(type(inst))    # the exception instance
...     print(inst.args)     # arguments stored in .args
...     print(inst)          # __str__ allows args to be printed directly,
...                          # but may be overridden in exception subclasses
...     x, y = inst.args     # unpack args
...     print('x =', x)
...     print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs


예외가 인자를 가지면, 처리되지 않은 예외 메시지의 마지막 부분('상세 명세')에 인쇄됩니다.

例外引数っていればそれらは処理されない例外のメッセージの最後部分 (詳細説明) 出力されます


 

예외 처리기는

try 절 내부 함수에서 발생하는 예외도 처리

 

例外ハンドラはtry 直接内側発生した例外処理するだけではなくその try から (たとえ間接的にでも) された関数内部発生した例外処理します


えば:

 

>>> def this_fails():
...     x = 1/0
...
>>> try:
...     this_fails()
... except ZeroDivisionError as err:
...     print('Handling run-time error:', err)
...
Handling run-time error: division by zero





8.4. 예외 일으키기 例外送出する


raise

지정한 예외를 강제로 발생시킴

     raise 使って特定例外発生させることができますえば:

 

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: HiThere


raise 인자 : 발생시킬 예외

예외 인스턴스이거나 예외 클래스 (Exception 를 계승하는 클래스)

예외 클래스가 전달되면, 묵시적으로 인자 없이 생성자를 호출해서 인스턴스를 만듭니다:


raise 唯一引数送出される例外します。 

これは例外インスタンスか例外クラス (Exception 継承したクラス) でなければなりません。 

例外クラスがされた場合引数無しのコンストラクタがされ暗黙的にインスタンスされます:

 

 

raise ValueError  # shorthand for 'raise ValueError()'



만약 예외가 발생했는지는 알아야 하지만 처리하고 싶지는 않다면

더 간단한 형태의 raise 문이 그 예외를 다시 일으킬 수 있게 합니다:

  

例外発生したかどうかを判定したいだけでその例外処理するつもりがなければ

単純形式raise 使って例外再送出させることができます:

 

 

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere





8.5. 사용자 정의 예외 ユーザー定義例外


새 예외 클래스를 만들 수 있음.

예외는 Exception클래스에서 파생함

     

プログラムしい例外クラスを作成することで独自例外指定することができます (Python のクラスについては クラス 参照)

例外典型的Exception クラスから直接または間接的派生したものです

 

 

예외 클래스는 

다른 클래스들이 할 수 있는 어떤 것도 가능하도록 정의될 수 있지만, 보통은 간단하게 유지합니다.

종종 예외 처리기가 에러에 관한 정보를 추출할 수 있도록 하기 위한 몇 가지 어트리뷰트들을 제공하기만 합니다.


여러 가지 서로 다른 에러들을 일으킬 수 있는 모듈을 만들 때

흔히 사용되는 방식은 모듈에서 정의되는 예외들의 베이스 클래스를 정의한 후

각기 다른 에러 조건마다 특정한 예외 클래스를 서브 클래스로 만드는 것입니다:


例外クラスでは普通のクラスができることならでも定義することができますが通常単純なものにしておきます大抵いくつかの属性だけを提供例外発生したときにハンドラがエラーにする情報せるようにする程度にとどめます複数別個例外送出するようなモジュールを作成するにはそのモジュールで定義されている例外基底クラスを作成するのが一般的なプラクティスです:

 

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message


대부분의 예외는 표준 예외들의 이름들과 유사하게, "Error" 로 끝나는 이름으로 정의됩니다.

 

ほとんどの例外標準例外名前付けと同様"Error" わる名前定義されています

 

 

 

많은 표준 모듈들은 그들이 정의하는 함수들에서 발생할 수 있는 그 자신만의 예외들을 정의합니다. 클래스에 관한 더 자세한 정보는 클래스 장에서 다룹니다.

 

くの標準モジュールではモジュールで定義されている関数内発生する可能性のあるエラーを報告させるために独自例外定義していますクラスについての詳細情報は クラス 提供されています

 

 

 


8.6. 뒷정리 동작 정의하기 クリーンアップ動作定義する


try 문은 또 다른 선택적 절을 가질 수 있는데 모든 상황에 실행되어야만 하는 뒷정리 동작을 정의하는 데 사용됩니다. 예를 들어:

 

try にはもうつオプションのがありますこのはクリーンアップ動作定義するためのものでどんな状況でも実行されますします:

 

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...
Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>


finally 절 은 예외의 발생 여부와 관계없이 try 문을 떠날 때 항상 실행됩니다. try 절에서 예외가 발생하고 except 절에서 처리되지 않으면 (또는 except else 절에서 발생하면), finally절이 실행된 후에 다시 일으킵니다. finally 절은 try 문의 다른 모든 절에서 break, continue, return 문에 의해 "빠져나가는 길에" 도 실행됩니다. 더 복잡한 예는 이렇습니다:

 

 

 

finally (finally clause) 例外発生したかどうかにわらずtry ける実行されますtry 例外発生してexcept 処理されていない場合 (つまり except else 例外発生した場合) finally 実行したその例外再送出しますtry から break continue return 文経由けるにもfinally "ける途中" 実行されますより複雑です:

 

 

 

>>> def divide(x, y):
...     try:
...         result = x / y
...     except ZeroDivisionError:
...         print("division by zero!")
...     else:
...         print("result is", result)
...     finally:
...         print("executing finally clause")
...
>>> divide(2, 1)
result is 2.0
executing finally clause
>>> divide(2, 0)
division by zero!
executing finally clause
>>> divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'


보인 바와 같이, finally 절은 모든 경우에 실행됩니다. 두 문자열을 나눠서 발생한 TypeErrorexcept 절에 의해 처리되지 않고 finally 절이 실행된 후에 다시 일어납니다.

 

 

 

てわかるとおりfinally はどの場合にも実行されています文字列をすることで発生した TypeError except 処理されていないのでfinally 節実行後再度送出されています

 

 

 

실제 세상의 응용 프로그램에서, finally 절은 외부 자원을 사용할 때, 성공적인지 아닌지와 관계없이, 그 자원을 반납하는 데 유용합니다 (파일이나 네트워크 연결 같은 것들).

 

 

 

実世界のアプリケーションではfinally (ファイルやネットワーク接続などの)外部リソースを利用成功したかどうかにかかわらず解放するために便利です

 

 

 


8.7. 미리 정의된 뒷정리 동작들 定義済みクリーンアップ処理


객체에는 객체가 더 필요 없을 때 개입하는 표준 뒷정리 동작을 정의

객체를 사용하는 연산의 성공 여부와 관계없습니다


파일을 열고 그 내용을 화면에 인쇄하려고 하는 다음 예를 보세요.

 

オブジェクトのなかにはその利用成否にかかわらず不要になった実行される標準的なクリーンアップ処理定義されているものがあります以下ファイルをオープンして内容画面表示するをみてください


for line in open("myfile.txt"):
    print(line, end="")


 코드의 문제점은 이 부분이 실행을 끝낸 뒤에도 예측할 수 없는 기간 동안 파일을 열린 채로 둔다는 것입니다

간단한 스크립트에서는 문제가 되지 않지만, 큰 응용 프로그램에서는 문제가 될 수 있습니다

with 문은 파일과 같은 객체들이 즉시 올바르게 뒷정리 되도록 보장하는 방법을 제공합니다.


このコードの問題点コードの実行わった不定時間ファイルをいたままでいることです

これは単純なスクリプトでは問題になりませんがきなアプリケーションでは問題になりえます。 

with はファイルのようなオブジェクトが即座しくクリーンアップされることを保証します


with open("myfile.txt") as f:
    for line in f:
        print(line, end="")


문장이 실행된 후에, 줄을 처리하는 데 문제가 발생하더라도, 파일 f 는 항상 닫힙니다

파일과 같이, 미리 정의된 뒷정리 동작들을 제공하는 객체들은 그들의 설명서에서 이 사실을 설명합니다.


この実行されたあとでたとえ処理中問題があったとしてもファイル f close されますファイルなどの定義済みクリーンアップ処理つオブジェクトについてはそれぞれのドキュメントでされます