5

この概念は以前にも出てきたと思いますが、適切で簡単な答えが見つかりません。複数の戻り値を持つ関数を処理するために try/finally を使用するのは悪い方法ですか? たとえば、私は


try:
    if x:
        return update(1)
    else:
        return update(2)
finally:
    notifyUpdated()

これは、 update() コマンドを一時変数に格納してそれを返すよりも優れているように思えます。

4

6 に答える 6

11

私はそれをお勧めしません。最初の理由notifyUpdated()は、いずれかのブランチのコードが例外をスローした場合でも呼び出されるためです。意図した動作を実際に得るには、次のようなものが必要です。

try:
    if x:
        return update(1)
    else:
        return update(2)
except:
    raise
else:
    notifyUpdated()

第二に、tryブロックは通常、何らかの例外処理を行っていることを示しますが、そうではないため、便宜上ブロックを使用しているだけです。したがって、この構造は人々を混乱させます。

たとえば、あなたの質問に答えた最初の 2 人 (少なくとも 1 人は回答を削除した) のどちらも、あなたが本当にやろうとしていることを理解していなかったと思います。どんなに便利で巧妙に見えても、紛らわしいコードは良くありません。

于 2010-08-16T21:16:35.540 に答える
11

例外を伴わないフローには、try/finally を使用しません。それはそれ自身の利益のためにはあまりにもトリッキーです。

これの方が良い:

if x:
    ret = update(1)
else:
    ret = update(2)
notifyUpdated()
return ret
于 2010-08-16T21:22:00.450 に答える
3

これはトラブルを求めていると思います。コードを次のように変更すると、後でどうなりますか?

try:
    if x:
        return update(1)
    elif y:
        return update(2)
    else:
        return noUpdateHere()
finally:
    notifyUpdated() # even if noUpdateHere()!

try/finallyせいぜい、通常の使用パターンとは異なる目的で使用しているため、コードのほとんどの読者 (おそらく 6 か月後のあなたでさえ) にとってつまずきポイントです。とにかく、それが節約するタイピングは最小限です。

于 2010-08-16T21:26:07.827 に答える
3

これの代わりに try/finally を使用したいということだと思います:

if x:
    result = update(1)
else:
    result = update(2)
notifyUpdated()
return result

これはスタイルの問題だと思います。私にとっては、try例外的な条件を処理するために予約するのが好きです。フロー制御ステートメントとしては使用しません。

于 2010-08-16T21:21:58.257 に答える
3

ここではデコレータの方が良い考えだと思います

def notifyupdateddecorator(f):
    def inner(*args, **kw):
        retval = f(*args, **kw)
        notifyUpdated()
        return retval
    return inner

@notifyupdateddecorator
def f(x):
    if x:
        return update(1)
    else:
        return update(2)

@notifyupdateddecorator
def g(x):
    return update(1 if x else 2)
于 2010-08-16T22:45:31.907 に答える
0

http://docs.python.org/library/contextlib.htmlから:


from contextlib import closing
import urllib

with closing(urllib.urlopen('http://www.python.org')) as page:
    for line in page:
        print line

同様の関数を作成して使用できます

于 2010-08-16T21:15:17.847 に答える