在try catch python中捕获stderr自定义输出

时间:2016-02-17 21:41:34

标签: python io

我有一个函数会在发生错误时写入stderr:

class Scanner:
    ...

    def next(self):
       if ...
            ...
            if not open_comment_count == closed_comment_count:
                        ...
                        sys.stderr.write("error: unclosed comment at position ({0}, {1})".format(start_position, end_position))
                        ...
                        break
            ...

       else:
            sys.stderr.write("error: illegal character \'{0}\' found " \
                          "at position @({1}, {2})".format(self.input_text[self.curr_position],
                                                           self.curr_position, self.curr_position))
                    error_flag = 1
                    break
      if error_flag == 0:
            token = Token(kind=4, eof_value="eof", start_position=self.curr_position, end_position=self.curr_position)
            return token

函数很长,所以我把所写的部分包括在stderr中。我想要做的是当这些错误发生时,我想打印这些错误并终止程序。所以在我的主要内容中,我希望:

def main():
    s = Scanner(input_string)
    try:
        while(True):
            s.next()
    except:
        # print error message and stop

我所坚持的是异常应该是什么。我想以某种方式抓住某些东西被写入stderr并且我希望抓住并打印出main,然后程序停止。基本上运行直到发生异常。我知道这可以通过编写我自己的异常来完成,但是是否可以检查是否有东西写入stderr然后将其打印出来?

3 个答案:

答案 0 :(得分:2)

而不是写入stderr是否有一个原因,你不能只是将你写入stderr的错误作为消息引发错误?然后你可以抓住你决定提出的任何错误。像

这样的东西
class Scanner:
...

def next(self):
   if ...
        ...
        if not open_comment_count == closed_comment_count:
                    ...
                    raise InputError("error: unclosed comment at position ({0}, {1})".format(start_position, end_position))
                    ...
                    break
        ...

   else:
        raise InputError("error: illegal character \'{0}\' found " \
                      "at position @({1}, {2})".format(self.input_text[self.curr_position],
                                                       self.curr_position, self.curr_position))
                error_flag = 1
                break
  if error_flag == 0:
        token = Token(kind=4, eof_value="eof", start_position=self.curr_position, end_position=self.curr_position)
        return token

然后

def main():
s = Scanner(input_string)
try:
    while(True):
        s.next()
except InputError as e:
    print e

EDIT 解决你的评论,是的。如果您想要使用自定义错误名称来执行此操作

class MyException(Exception):
    pass

然后raise MyException('message')

答案 1 :(得分:2)

您想要做的事情混淆了问题:报告错误会成为 错误的信号。你可以通过为stderr创建一个设置某种标志的包装器来实现这一点:

import sys

class MyStdErr(object):

    stderr = sys.stderr
    waserr = False

    def write(self, text):
        self.waserr = True
        self.stderr.write(text)

sys.stderr = MyStdErr()

如果sys.stderr.waserr在任何时候被写入,则Truestderr

我认为提出包含错误消息的异常,捕获它并打印错误(如Nathan所示)的情况要好得多。

答案 2 :(得分:0)

如果要在写入stderr时导致异常,请关闭stderr。现在当某个函数写入stderr时,我猜它会得到一个IOError。获取错误消息会更难。

您可以捕获所有异常并打印出异常,但这仍然无法将消息捕获到stderr。