1

.callback()orを呼び出す.errback()と、呼び出し元に例外が発生し、遅延オブジェクトによってキャプチャされないという状況が発生する可能性はありますか?

次の遅延およびコールバックがあるとします。

from twisted.internet import defer

def bad_callback(result):
    raise Exception()

def bad_errback(result):
    raise Exception()

d = defer.Deferred()
d.addCallbacks(bad_callback, bad_errback)

を呼び出すとd.callback(None)、の結果はfromにdなります。を呼び出すと、 の結果はから発生したものになります。ただし、いずれの場合も、例外は呼び出し元に発生しません。Exceptionbad_callback()d.errback(Exception())dExceptionbad_errback()

.callback()現在、 orを呼び出すと呼び出し元に例外が発生するいくつかの条件を知ってい.errback()ますが、それらは deferred の適切な使用に違反する条件です。

  • 明らかに、不適切な数の引数で.callback()またはを呼び出すと、 ..errback()TypeError

  • すでに呼び出されている deferred を呼び出すと、 が発生しAlreadyCalledErrorます。

  • を呼び出す.callback(defer.Deferred())と、 が発生しAssertionErrorます。

  • 呼び出しは、アクティブな例外がない場合に発生する.errback()呼び出しと同等です。.errback(failure.Failure())NoCurrentExceptionError

本当に私の質問は次のとおりです。遅延オブジェクトがまだ呼び出されておらず、結果が適切である限り、.callback(result)orを呼び出しても例外が発生しないという動作に安全に依存できますか?.errback(exception_or_failure)

4

1 に答える 1

2

私はあなたの例を実行し、下に2行を追加しました:

d.callback(None)
print("OK!")

そして、この出力を得ました:

Unhandled error in Deferred:
Unhandled Error
Traceback (most recent call last):
  File "callbacks.py", line 11, in <module>
    d.callback(None)
  File ".../twisted/internet/defer.py", line 368, in callback
    self._startRunCallbacks(result)
  File ".../twisted/internet/defer.py", line 464, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File ".../twisted/internet/defer.py", line 551, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "callbacks.py", line 4, in bad_callback
    raise Exception()
exceptions.Exception: 
OK!

したがって、この特定のケースでは (自分で決定したように)、いいえ、例外は再発生しません。

一般に、例外が効果的に伝播する場所がいくつかあります。MemoryError完全にメモリが不足しているために a がある場合、Deferred実装自体が関数または何かを呼び出そうとしてどこかに小さなメモリを割り当て、その例外が戻ってくる可能性があります。

しかし、これは Python でプログラミングする一般的なリスクにすぎません。警告なしで発生する可能性のあるいくつかの例外 ( MemoryError、 ) があります。KeyboardInterruptプロセス全体が燃え尽きていない場合は、いいえ、概説した場合を除いて例外は発生しませんcallbackerrback

于 2014-03-11T18:49:53.427 に答える