如何优雅地捕捉错误并保持方法清洁?

时间:2009-08-12 03:59:31

标签: python

我正在编写一个小的(呃)Python脚本来自动化一个半频繁,冗长且容易出错的任务。该脚本负责进行各种系统调用 - 通过os.system或os。(mkdir | chdir | etc)。

以下是我的代码示例:

class AClass:

    def __init__(self, foo, bar, verbose=False, silent=False):
        # Sets up variables needed for each instance, etc
        self.redirect = ''
        if silent:
            self.redirect = '> 2>&1'
        self.verbose = verbose

    def a_method(self):
        """ Responsible for running 4-6 things via system calls as described """

        if self.verbose and not self.silent:
            print "Creating a directory"
        try:
            os.mkdir('foobar')
        except OSError, e:
            raise OSError, "Problem creating directory %s: %s" % (e.filename, e.strerror)

        if self.verbose and not self.silent:
            print "Listing a directory"
        if (os.system('ls foobar %s') % self.redirect) is not 0:
            raise OSError, "Could not list directory foobar"

    def b_method(self):
        """ Looks very similar to a_method() """

    def run(self):
        """ Stitches everything together """

        try:
            a_method()
        except OSError, e:
            print "a_method(): %s" % e.strerror
            sys.exit(-1)

        try:
            b_method()
        except OSError, e:
            print "b_method(): %s" % e.strerror
            sys.exit(-1)

显然,写下所有if self.verbose and not self.silent是混乱的,然后每个调用周围的try/catchif都很难看。 我本来希望使用Python的日志记录类,只需通过命令行配置一个日志级别(详细),然后我可以简单地调用logger.debug('My message')但我使用的是Python 2.2,我无法访问{{1 }。class。

摘要/基本问题
我使用的是Python 2.2,我无法改变它。我在ESX 3.0.2服务器上运行,暂时无法以任何其他方式触摸它 什么是处理错误检查和详细输出而不将此逻辑绑定到您的类(这应该只做一件事)的最佳方法?
如何通过更简单或更优雅的东西来减少混乱?

谢谢!

2 个答案:

答案 0 :(得分:4)

如何清理详细输出

将详细/静默逻辑移动到单个函数中,然后为所有输出调用该函数。如果你做得好而且简短,那么你的主线代码就会非常整洁。

def P(s):
    if (verbose):
        print s

我有一个在我们的内部代码中执行此操作的包,它具有以下方法:

  • P - 正常打印:P('this prints regardless, --quiet does not shut it up')
  • V - 详细打印:V('this only prints if --verbose')
  • D - 调试打印:D('this only prints if --debug')

答案 1 :(得分:4)

writing all the if verbose and not silent is messy

所以,相反,将sys.stdout分配给一个伪类,如果你需要unverbose或silent,那么它的写操作是无操作,那么只需使用print而不需要保护。 (请记住将sys.stdout恢复到真实的东西,以获得不那么条件的打印件 - 实际上更容易封装在几个函数中)。

对于错误检查,所有块如:

    try:
        a_method()
    except OSError, e:
        print "a_method(): %s" % e.strerror
        sys.exit(-1)

可以而且应该像

    docall(a_method)

我希望这是一个非常明显的def docall(acallable):

类似地,其他try / except case和有条件地引发新异常的那些可以成为具有适当参数的函数的调用(包括callables,即高阶函数)。如果你澄清哪些内容很难或不清楚,我会很高兴添加详细的代码!

Python 2.2虽然现在已经很老了,但却是一种很好的语言,并且可以像你希望的那样整齐地使用它,就像其它伟大的旧语言一样,比如MacLisp; )。