0

過去に、次のような try-except 句を書いていることに非常に気付きました。これの主な理由は、より少ないコードを記述することです。

class Synchronizer(object):
    # ...

    def _assert_dir(self, dirname, argname, argnum):
        """ *Private*. Raises OSError if the passed string does not point
            to an existing directory on the file-system. """

        if not os.path.isdir(dirname):
            message = 'passed `%s` argument (%d) does not point to a ' \
                      'directory on the file-system.'
            raise OSError(message % (argname, argnum))

    def synchronize(self, source_dir, dest_dir, database):

        # Ensure the passed directories do exist.
        try:
            self._assert_dir(source_dir, 'source_dir', 2)
            self._assert_dir(dest_dir, 'dest_dir', 3)
        except OSError:
            raise

        # ...

そうでなければ私は書く必要があったので、私はこのようにしていた

class Synchronizer(object):
    # ...

    def synchronize(self, source_dir, dest_dir, database):

        # Ensure the passed directories do exist.
        if not os.path.isdir(source_dir):
            message = 'passed `source_dir` argument (2) does not point to a ' \
                      'directory on the file-system.'
            raise OSError(message)

        if not os.path.isdir(dest_dir):
            message = 'passed `dest_dir` argument (3) does not point to a ' \
                      'directory on the file-system.'
            raise OSError(message)

        # ...

私は実際には、チェック アンド レイズ操作を行うメソッドを記述するというアイデアが好きですが、大きな欠点が 1 つあります。それは、読みやすさです。特にコードの折り畳みを行うエディターにとって、tryステートメントは読者に内部で何が起こっているかをあまり伝えていませんが、if not os.path.isdir(source_dir)かなり良いヒントです。

IMHO try-except 句が必要なのは、例外の発生元である例外のキャッチャー(トレースバックのリーダー) を混乱させるためです。

このデザインについてどう思いますか?それはあなたにとってひどいですか、素晴らしいですか、それとも混乱しますか? または、状況を改善する方法について何かアイデアはありますか?

4

2 に答える 2

2

例外条件を処理するために try を使用する前に 2 つの質問を自問し、両方の答えが YES の場合にのみ、例外を処理しようとします。

Q1. これは本当に例外的なシナリオですか? 条件が 90% の確率で発生する場合は、try ブロックを実行したくありません。そのような場合は if - else を使用することをお勧めします。

Q2. エラーから回復できますか? 例外から回復できない場合、例外を処理する意味はほとんどありません。余分なコードを書かなくても、自動的に発生するより高いレベルに伝播する方が良いでしょう。

ディレクトリが存在しない場合、あなたが投稿したコードは回復するために何もしません。それについてあなたができることはあまりありません。エラーをより高いレベルに伝播させないのはなぜですか? なぜそこに try ブロックが必要なのですか?

于 2012-10-13T21:16:31.073 に答える
1

これはあなたの要件に依存します..

  • 何らかの例外をキャッチし、メソッド内のコードを続行する場合は、2 番目のシナリオを使用する必要があります。メソッド内で try-except ブロックを作成してください。

    def function():
       try:
          raise IOError
       except IOError e:
          // Handle
       //continue with reset of the function
       print "This will get printed"
    
    function()
    
  • ただし、すべての例外を 1 か所で特定のタイプの特定のアクションで処理したい場合、または単に関数を停止したい場合は、1 つの例外が発生した場合、関数の外でより適切に処理できます。

    def function():
       raise IOError
    
       // subsequent code Will not execute
       print "This will not get printed"
    
    try:
       function()
    except IOError e:
       // Handle IOError
    except EOFError e1:
       // Handle EOF Error
    
  • 2 番目の方法を使用すると、コードの一部が実行されない可能性が実際に高くなります。一般に、try-except ブロックはsmall. 異なるポイントで例外を処理するためにそれらを分離する必要があり、すべての例外を 1 か所で処理する必要はありません。

  • 私に関する限り、私は通常、try-except ブロックを可能な限り最小限に抑えたいと考えています。そうすれば、例外がどこで発生したかを正確に知ることができます。
于 2012-10-13T21:10:13.860 に答える