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)

        # ...

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

恕我直言,try-except 子句是必需的,因为它会混淆异常来自的异常捕获器(回溯的读取器)。

你觉得这个设计怎么样?它对你来说是可怕的、伟大的还是令人困惑的?或者您对如何改善这种情况有任何想法?

4

2 回答 2

2

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

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

Q2。我可以从错误中恢复吗?如果我无法从异常中恢复,则处理异常毫无意义。最好将它传播到更高级别,这会自动发生,而无需我编写额外的代码。

如果目录不存在,您发布的代码不会做任何恢复,而且您似乎无法做很多事情。为什么不让错误传播到更高的层次呢?为什么你甚至需要一个 try 块呢?

于 2012-10-13T21:16:31.073 回答
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 块。这样我就知道我的异常到底是在哪里引发的。
于 2012-10-13T21:10:13.860 回答