私はPythonのリソース処理に関するwith文について知っています。 Pythonの例外安全なコードには他にどんな懸念がありますか?Pythonの例外安全性の状態は何ですか?
編集:ここでの懸念は、ファイルなどを開くことです。たとえば、init関数が例外を発生させたとします。初期化されているオブジェクトの状態は何ですか?
私はPythonのリソース処理に関するwith文について知っています。 Pythonの例外安全なコードには他にどんな懸念がありますか?Pythonの例外安全性の状態は何ですか?
編集:ここでの懸念は、ファイルなどを開くことです。たとえば、init関数が例外を発生させたとします。初期化されているオブジェクトの状態は何ですか?
私は、@ S.Lott答えにコメントでそのフラグメントを投稿することができませんでしたFor instance, suppose an init function raises an exception. What is the state of the object being initialized?
ヒント。不確かな場合は、実際に実験を行います。
>>> class Partial(object):
... def __init__(self):
... self.a= 1
... raise Exception
... self.b= 2
...
>>> p= Partial()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in __init__
Exception
>>> p
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'p' is not defined
文全体が失敗します。オブジェクトが作成されていません。変数が割り当てられていません。 他に質問がありますか?
C++では、物事ははるかに複雑です。 Pythonでは、オブジェクトは単に破棄されます。
疑問があるときに誰もが実験をしたのであれば、私たちはPythonの質問に比べて非常に良いアドバイスです:-) –
@ THC4k誰かが尋ねていることをしばしば試して結果を投稿すると、固い答え。 Sshhh ...誰にも言わないでください... – JAL
@ THC4k一方、実験だけではなく、より深い知識を身につけるように尋ねると良いです。 –
PythonはC++に似ていません。例外は有用なバックトレースを生成します。ユーザーの入力を受けている場合は、適切な例外(例:EOFError
)をキャッチします。それ以外の場合は、特別な操作を行う必要はありません。プログラムが予期せぬことをして例外をスローした場合は、結果のスタックダンプを使用して問題をデバッグしてください。非常に高い可用性を実現するには、ログのループ内でtry/except
を使用して最上位レベルをラップして再起動する必要があります。
強力な例外安全性は、バックトレースなどとは何の関係もありません。例外が発生した場合、システムが一貫性のある状態になっている場合、これが行われます。 Pythonがjavaのような 'try'ブロック内のすべてを実行してからすべての変更を適用しない限り...状態が変更されない限り例外が適用されない限り、Python自体は本質的にS.E.S.はい、S.E.S. C++ではこれもやりにくいです。 「キャッチ」例外を除外できないだけではありません。 – mawalker
あなたは言語構造について尋ねている場合:
try: except: else:
それはあなたが間違った例外をキャッチしないことを保証します。BaseException
をキャッチする前に、よく考えException
またはあなたはイースリーくらいにキャッチすることができますよう except:
裸を使用します。
log.exception('your message', e)
StopIteration
のような(Pythonで例外は、通常のフロー制御にも使用されていることに注意してください例外)except MyException, myex:
の代わりにexcept MyException as myex:
という新しい構文を使用します。経験豊富なPython開発者にとっては読みやすいです。あなたが代わりに常にオープンでcodecs.open使用するテキストファイルを読み込む場合は、ファイルについて
try:
this_doesn_not_exisit();
except Exception: #Don't do that!
pass
print "But this line is still printed"
回答:ここで
__init__
については、オブジェクトの状態。 __init__
はイニシャライザですので、__init__
を呼び出すとオブジェクトが既に存在します。例外を発生させると、フローは中断され、オブジェクトは変数に格納されないため、ガベージコレクションされます。少なくともそれは私の理解です。 MyObject()は何も返さない例外を発生させ、フローが中断され、代入していた値が変更されていない場合に値を返す関数であると考えてください。このうちチェック:
>>> def throw(): raise Exception()
...
>>> a=1
>>> a=throw()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 1, in throw
Exception
>>> a
1
ここでは、あなたが__init__
で例外を発生させても、オブジェクトが作成されていることを証明する一例です。
>>> global_collection=[]
>>> class Partial(object):
... def __init__(self):
... self.test="test"
... global_collection.append(self)
... raise Exception()
...
>>> x=Partial()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __init__
Exception
>>> global_collection
[<__main__.Partial object at 0xb74f8f6c>]
>>> global_collection[0].test
'test'
UPDATE:によってなさ 含まコメント:@Paulマクガイア、@martineau、@aaronasterling
私は最後にtry:except:else:を追加します。 finally節は、どのエラーがポップアップされたか(一時保存されているかどうかにかかわらず)、ファイルが閉じられ、リソースが解放されることを保証するのに最適です。 http://docs.python.org/reference/compound_stmts.html#try –
FWIWでは、実際に構文エラーを検出することはできません。そのエラーは、プログラムがコンパイルされて実行される前に発生し、 'try'ステートメントはその時点では実行されていません。 – aaronasterling
最初の例で構文エラーはありません。 'this_doesn_not_exisit();'は構文的には問題ありません。しかし、 'this_doesn_not_exisit'という名前がないので、' NameError'例外が発生します。 Aaronが説明したように、「except」も、一般的なものでさえも、「SyntaxError」をキャッチすることはできません(しかし、あなたのアドバイスはそうでなければ一般的に有効です)。 – martineau
あなたはどういうことを言っていますか?何の安全?これはかなり広い話題のようです。あなたの質問は何ですか? – Falmarri
オブジェクトは '__init __()'が呼び出される前にすでに存在しています。これは、通常は 'self'と呼ばれる最初の引数ですが、まだ初期化されていません。そのプロセス中に例外が発生した場合、例外の処理方法や内容によっては、部分的または完全に初期化されないこともあります。 – martineau
ここでは、 '__init __()'メソッドで発生した例外がどのように処理されたかによって、オブジェクトが正しく初期化されなかったことを示しています:![example code](http://dl.dropbox.com/u/5508445/stackoverflow /__init__exception.png)。 – martineau