代码之家  ›  专栏  ›  技术社区  ›  Nick Presta

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

  •  1
  • Nick Presta  · 技术社区  · 15 年前

    我正在编写一个小型(ER)python脚本来自动执行一个半频繁、长且容易出错的任务。此脚本负责进行各种系统调用-通过os.system或os(mkdir chdir等)。

    下面是我的代码示例:

    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/catch if 每个电话的周围都难看。 我想使用Python的日志类,只需通过命令行配置一个日志级别(详细),然后我就可以简单地调用 logger.debug('My message') 但是我使用的是python 2.2,我没有访问 logging 班级。

    总结/基础问题
    我使用的是python 2.2,不能更改它。我在一台esx 3.0.2服务器上运行,暂时无法以任何其他方式触摸它。
    处理错误检查和详细输出的最佳方法是什么,而不将此逻辑绑定到类(类只应做一件事)?
    我怎样才能用更简单或更优雅的东西来减少杂乱?

    谢谢!

    2 回复  |  直到 15 年前
        1
  •  4
  •   Alex Martelli    15 年前
    writing all the if verbose and not silent is messy
    

    因此,相反,将sys.stdout分配给一个虚拟类,如果您需要不冗长或静默,那么就使用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和有条件引发新异常的case可以成为对具有适当参数(包括可调用函数,即高阶函数)的函数的调用。如果您能澄清其中哪些部分对您来说很难或不清楚,我很乐意添加详细的代码!

    虽然python 2.2现在已经很老了,但它在某种程度上是一种很好的语言,正如您希望的那样,整洁地使用它,就像使用其他伟大的旧语言一样,比如说maclisp;-)。

        2
  •  4
  •   Mark Harrison    15 年前

    如何清除冗长的输出

    将详细/安静逻辑移到一个函数中,然后为所有输出调用该函数。如果你把它做得又好又短,它会让你的主线代码保持整洁。

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

    我有一个在内部代码中这样做的包,它有以下方法:

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