AttributeError:StringIO实例没有属性“ fileno”

发布于 2021-01-29 17:28:25

def captureOutput(self, func, *args, **kwargs):
    pass
    sys.stdout.flush()
    sys.stderr.flush()
    (outfd, fn) = tempfile.mkstemp()
    fout = os.fdopen(outfd, 'r')
    os.unlink(fn)
    (errfd, fn) = tempfile.mkstemp()
    ferr = os.fdopen(errfd, 'r')
    os.unlink(fn)
    try:
        oldstdout = os.dup(sys.stdout.fileno())
        oldstderr = os.dup(sys.stderr.fileno())
        os.dup2(outfd, sys.stdout.fileno())
        os.dup2(errfd, sys.stderr.fileno())
        try:
            ret = func(*args, **kwargs)
        finally:
            sys.stderr.flush()
            sys.stdout.flush()
            os.dup2(oldstdout, sys.stdout.fileno())
            os.close(oldstdout)
            os.dup2(oldstderr, sys.stderr.fileno())
            os.close(oldstderr)

        os.lseek(outfd, 0, 0)
        out = fout.read()
        os.lseek(errfd, 0, 0)
        err = ferr.read()
    finally:
        fout.close()
        ferr.close()
    return ret, out, err

运行此代码时,出现错误:

AttributeError:StringIO实例没有属性“ fileno”

为什么会出现此错误,如何解决?

关注者
0
被浏览
154
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您是否在使用标准的纯Python解释器?当您使用覆盖stdout /
    stderr的解释器(例如IDLE)时,可能会出现此错误(尽管IDLE本身会给您带来其他错误)。它也可能是由覆盖stdout / stderr的库引起的。

    有时,您可以通过编写将stdout重置为默认stdout sys.stdout = sys.__stdout__,但不要指望它总是能正常工作。例如,它在Pythonwin中不起作用。

    无论如何,似乎您要对代码执行的操作是自己重定向stdout /
    stderr。如果是这样,您应该继续进行。我认为这应该工作,如果您有文件描述符outfderrfd

    sys.stdout = os.fdopen(outfd, 'w')
    sys.stderr = os.fdopen(errfd, 'w')
    

    编辑:

    现在,我可以看到您的整个代码,我将不再使用临时文件。

    def captureOutput(self, func, *args, **kwargs):
        import cStringIO # You can also use StringIO instead
    
        sys.stderr.flush()
        sys.stdout.flush()
        olderr, oldout = sys.stderr, sys.stdout
        try:
            sys.stderr = cStringIO.StringIO()
            sys.stdout = cStringIO.StringIO()
            try:
                ret = func(*args, **kwargs)
            finally:
                stderr.seek(0)
                stdout.seek(0)            
                err = stderr.read()
                out = stdout.read()
        finally:
            sys.stderr = olderr
            sys.stdout = oldout
    
        return ret, out, err
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看