Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python AttributeError:StringIO实例没有属性';文件编号';_Python - Fatal编程技术网

Python AttributeError:StringIO实例没有属性';文件编号';

Python AttributeError:StringIO实例没有属性';文件编号';,python,Python,运行此代码时,我收到一个错误: 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() fe

运行此代码时,我收到一个错误:

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” 为什么会出现此错误以及如何更正它?

StringIO中未实现
fileno()
方法,因为它不是真实的文件(因此没有关联的文件描述符)。来源:

AttributeError: StringIO instance has no attribute 'fileno' 可能有人用StringIO实例替换了sys.stdout以捕获输出

例如,当我以这种方式运行代码时,会得到相同的异常:

- fileno() is left unimplemented so that code which uses it 
triggers an exception early.
错误:

from StringIO import StringIO
sys.stdout = StringIO()
captureOutput(testfunc)

最好从头到尾跟踪代码,查找被覆盖的点
sys.stdout
。下面是一个示例,展示了如何在跟踪处于活动状态时执行代码:

    oldstdout = os.dup(sys.stdout.fileno())
AttributeError: StringIO instance has no attribute 'fileno'

我猜可能是代码中的其他地方,sys.stdout或sys.stderr被重新分配为StringIO的实例。这段代码是在什么环境下运行的(比如在某个web框架内,从命令行执行)?这可能会给熟悉该环境的人提供正确答案的线索。

您使用的是标准的纯python解释器吗?当您使用重写stdout/stderr的解释器时,例如IDLE(尽管IDLE本身会给您一个不同的错误),可能会出现此错误。它也可能是由重写stdout/stderr的库引起的

有时,您可以通过写入sys.stdout=sys.\uu stdout\uuu将标准输出重置为默认标准输出,但不要指望它总是工作。例如,它在蟒蛇身上不起作用

不管怎么说,似乎您试图对代码做的是自己重定向stdout/stderr。如果是这样的话,你应该继续做下去。如果您有文件描述符
outpd
errfd
,我认为这应该是可行的:

ares% python -m trace -c -t -C ./coverage test_sio.py | grep sys.stdout
test_sio.py(47): sys.stdout = StringIO()
编辑: 现在我可以看到你的全部代码了,我根本不会使用临时文件

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

简而言之,您在标准库中遇到了一个bug。StringIO未履行其IOBase类的契约。某个类写入IOBase类接口,然后该接口失败

更具体地说,Subprocess.run()或其他一些函数使用IOBase fileno函数。子类StringIO引发此异常,因为它不是真正的子类。在某个地方,IOBase的许多用户中有一个失败了。记录StringIO无助于解决此问题


也许你可以围绕它编码。也许不是。像contextlib.redirectstdout()这样的所有函数都将失败。

需要更多的代码,outpd和errfd是什么?您使用的是标准的纯python解释器吗?当您使用重写stdout/stderr的解释器时,例如IDLE(尽管IDLE本身会给您一个不同的错误),可能会出现此错误。这也可能是由重写stdout/stderr的库引起的。我找不到任何StringIO的导入,可能是因为使用了dup()和dup2()?这会导致错误吗?现在:dup()和dup2()解释如下:和返回文件描述符。dup(fd)返回文件描述符fd的副本。可用性:Unix、Windows。dup2(fd,fd2)将文件描述符fd复制到fd2,必要时先关闭后者。可用性:Unix、Windows。@kamal我不认为
dup()
会导致那个特定的错误。尝试访问缺少的
[obj].fileno
属性时发生异常。您是否在IDE下运行?可能您的IDE是在StringIO中交换的,如另一个答案中所述。我不是在IDE中运行,而是在shell(bash)中运行,因此我有一个bash脚本使用nosetests@kamal试试Python跟踪器-我已经用更多细节更新了我的答案。这是非常好的信息,谢谢,但我相信在本例中,test_sio.py是可执行的(该行是否没有if name_uuu==''uuuu main')正确?在我的例子中,使用Python2.7.5是不正确的。。。函数cStringIO.getvalue()不是代替了csStringIO.read()吗?另外,您不应该关闭cStringIO实例吗?
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