try-except-raise条款,良好的行为?

时间:2012-10-13 20:55:44

标签: python exception raise traceback

我注意到我过去曾经写过如下的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)

        # ...

我实际上喜欢编写执行检查和提升操作的方法,但我发现一个很大的缺点:可读性。特别是对于进行代码折叠的编辑器,try语句并没有告诉读者内部发生了什么,而if not os.path.isdir(source_dir)是一个很好的暗示。

恕我直言,try-except子句是必需的,因为它会混淆异常来自异常的 catcher (追踪的读者)。

您对此设计有何看法?这对你来说是可怕的,伟大的还是令人困惑的?或者您对如何改善这种情况有任何想法?

2 个答案:

答案 0 :(得分:2)

在使用try处理异常条件之前,我问自己有两个问题,如果两者的答案都是肯定的,那么我将尝试处理异常。

Q1。这真的是一个例外情况吗?如果条件在90%的情况下发生,我不想执行try块。在这种情况下,最好使用if - else。

Q2。我可以从错误中恢复吗?如果我无法从中恢复,那么处理异常就没什么意义了。最好将它传播到更高级别,这是自动发生的,而不必编写额外的代码。

如果目录不存在,那么您发布的代码无法恢复任何内容,并且您似乎无法对其进行任何操作。为什么不让错误传播到更高的级别?为什么你甚至需要一个试块?

答案 1 :(得分:1)

这取决于您的要求..

  • 如果要捕获一些异常,并继续使用方法中的代码,则应使用第二种方案。你有没有试过 - 在你的方法中阻止。

    def function():
       try:
          raise IOError
       except IOError e:
          // Handle
       //continue with reset of the function
       print "This will get printed"
    
    function()
    
  • 但是如果你想在一个地方处理所有异常,对特定类型采取特定的操作,或者你只想暂停你的功能,如果引发一个异常,你可以在你的函数之外更好地处理它们: -

    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
    
  • 通过使用第二种方式,实际上增加了某些代码无法执行的可能性。通常,您的try-except块应为small。它们应该在不同的点上分开处理异常,并不是所有例外都应该在一个地方处理。

  • 就我而言,我一般都希望尽量减少我的try-except块。这样我就知道我的异常在哪里了。