0

わかりやすくするために質問を編集しています。

MySQLdbをインポートするモジュールにクラスを作成しました。ユーザーがクラスに渡すテーブルが存在しない場合、MySQLdbで例外が発生することがわかりました。私はその例外をキャッチし、新しい例外をクライアントに渡します。しかし、クライアントが私の例外をキャッチしたとしても、プログラムは終了します。また、MySQLdbがクラスに与えるのと同じ例外をクライアントに渡そうとしました。

クライアントはループで私のメソッドを呼び出し、さまざまなテーブル名を渡すので、テーブル名が悪い場合にプログラムがチョークするのは望ましくありません。クライアントの反復を次の有効なテーブル名まで続行してほしい。スニペットは次のとおりです(tableNameはメソッドへの引数パスです):

私のクラス/モジュール:

    self.tableName = tableName
    試す:       
        self.cursor.execute( "select * from" + self.tableName + ";")#テーブルが存在しない場合は例外が発生します。
    それ外:
        MyException( "\ n ***" + self.tableName + "は存在しません。***")を発生させます

クライアントの場合:

    テーブル=["BadTableName"、 "GoodTableNameA"、 "GoodTableNameB"、 "GoodTableNameC"]

    試す:
        テーブル内のテーブルの場合:
            my_method(table)#ExceptionメッセージはBadTableNameで渡されますが、プログラムは終了します。このループのサブシークエストの反復は決して発生しません
    例外を除いて、e:
        eを印刷する

my_method(BadTableName)を呼び出した後も、クライアントに続行してもらいたい。

ちなみに、my_method()は、クライアントがインポートしている独自のモジュールで定義されたクラスの一部です。

ありがとうございました。

4

5 に答える 5

1

例外によってプログラムが終了するとは限りません。ドキュメントから:

実行中に検出されたエラーは例外と呼ばれ、無条件に致命的ではありません。

try:exceptブロックで例外が発生し、except句が例外または例外のスーパークラスを指定している場合、それが処理されます。

例外を処理するときは、例外を調べて、それに関連するすべての情報を見つけることができます。私はこれまでtracebackモジュールを使用したことがありませんが、必要なものがすべて含まれているようです。

2番目の質問は、ユーザーに何を見せたいかによって異なると思います。例外を表示する必要がありますか?(トレースバックにアクセスできます)。メッセージだけを表示する必要がありますか?トレースバックをログに記録する必要がありますか?

于 2013-02-22T20:00:06.900 に答える
1

finally他の回答に追加:キャッチされない例外はプログラムを終了しますが、該当するブロック(存在する場合)とatexitハンドラーを実行した後でのみ終了します。したがって、原則として、キャッチされない例外の後、無期限に実行を継続することが可能です。

ただし、エラーメッセージを出力し、その性質上実行を継続する例外のクラスはありません。それが必要な場合は、警告を使用してください。

于 2013-02-22T20:06:06.863 に答える
0

1)いいえ、例外を発生させてもプログラムが終了するとは限りません。キャッチされない例外により、プログラムは終了します。次のように、コードをブロックで囲んでtry/except、例外がスタックに伝播するのを防ぐことができます。

try:
    file = open("foo.txt")
except IOError:
    file = None

2)例外を実際にキャッチするコードは、例外の元のスタックフレームにアクセスでき、それをどう処理するかを決定できます。

元のトレースバックでエラーを再発生させます。

try:
    some_function()
except IOError as e:
    raise

新しいトレースバックを使用してエラーを再発生させます(最初のケースほど有用ではありません):

try:
    some_function()
except IOError as e:
    raise e

再起動せず、例外とトレースバックを出力します。

try:
    some_function()
except IOError as e:
    import traceback
    traceback.print_exc()
于 2013-02-22T19:58:48.277 に答える
0

キャッチされない例外はプログラムを終了します。キャッチされた例外は

例外がキャッチされた場合、トレースバックモジュールを使用してスタックトレースを出力できます。

http://docs.python.org/2/library/traceback.html#traceback-examples

于 2013-02-22T20:00:45.497 に答える
0

編集した質問を読んだ後、2つの問題のどちらが発生しているかわかりません。


問題が、ループ全体ではなく1つのループ反復のみを終了する例外が必要な場合は、ステートメントを明白な方法で再ネストするだけです。これの代わりに:

try:
    for table in tables:
        my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen
except Exception, e:
    print e

これを行う:

for table in tables:
    try:
        my_method(table) #Exception message gets passed in with BadTableName, but the program ends. Subsequest iterations of this loop never happen
    except Exception, e:
        print e

一方、問題がクライアントが例外をキャッチしていないことである場合、問題はあなたMyExceptionがのサブクラスではない可能性が高いですException。これが発生する可能性のある方法は少なくとも3つあります。

新しいスタイル()の代わりに古いスタイルのexcept構文( )を使用しているため、から継承しないクラスを発生させることができる古いバージョンのPythonを使用している可能性があります。例えば:except Exception, e:except Exception as e:BaseException

class MyException(object):
    def __init__(self, msg):
        pass

try:
    raise MyException("dsfsdf")
except Exception:
    pass

Pythonのバージョンによっては、を上げることができずMyException、代わりにTypeError(' Out[11]: TypeError('exceptions must be old-style classes or derived from BaseException, not MyException')(キャッチされる)を上げるか、警告を出力するか、要求どおりにサイレントに「動作」する場合があります(つまり、何もキャッチされません。プログラムはトレースバックで終了します)。


一方、2.7でも、古いスタイルのクラスを上げることができますが、これもキャッチされません。

class MyException:
    def __init__(self, msg):
        pass

try:
    raise MyException("dsfsdf")
except Exception:
    pass

これは常に例外のキャッチに失敗し、アプリはトレースバックで終了します。


BaseException最後に、の代わりにから継承した場合Exception、明らかにそれExceptionをキャッチしません。

class MyException(BaseException):
    def __init__(self, msg):
        pass

try:
    raise MyException("dsfsdf")
except Exception:
    pass

繰り返しになりますが、これは常にあなたが上げたものをキャッチするのに失敗し、あなたはトレースバックで終了します。

于 2013-02-22T20:50:34.087 に答える