异常ValueError:'未初始化对象上的I / O操作'

时间:2021-05-15 20:27:08

We have a small automation test process called run.py at work and inside the file there is a class called

我们有一个名为run.py的小型自动化测试过程,在文件中有一个名为的类

class flushfile(io.TextIOWrapper):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

it gives this error:

它给出了这个错误:

Exception ValueError: 'I/O operation on uninitialized object' in

Every time we run the tests but it does not seem to affect anything. The context of the class is that we are flushing the buffer after printing to a text file as well as the command line.

每次我们运行测试但它似乎没有影响任何东西。该类的上下文是我们在打印到文本文件以及命令行后刷新缓冲区。

sys.stdout = flushfile(sys.stdout)

Is how it is called in the code.

它是如何在代码中调用的。

For the life of me I can't figure out what it might be.

对于我的生活,我无法弄清楚它可能是什么。

1 个解决方案

#1


2  

You must add flush() method in your wrapper:

您必须在包装器中添加flush()方法:

class flushfile(io.TextIOWrapper):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
    def flush(self):
        self.f.flush()

A simple test is:

一个简单的测试是:

import sys
sys.stdout = flushfile(sys.stdout)
print("TEST")

Without flush() you will got the error when script dead and try to call flush() of new sys.stdout.

如果没有flush(),脚本死机时会出现错误,并尝试调用新sys.stdout的flush()。

Anyway with the original version if you recover stdout before exit you can have the same result:

无论如何,如果你在退出之前恢复stdout,你可以得到相同的结果:

import sys
orig = sys.stdout
sys.stdout = flushfile(sys.stdout)
print("TEST")
sys.stdout = orig

EDIT

Maybe you don't need to wrapper for file object but just a new write() method. Python is first a functional programming language and a more pythoninc way to do what you want to do is change sys.stdout.write method. Follow an implementation example:

也许你不需要为文件对象包装,而只需要一个新的write()方法。 Python首先是一种函数式编程语言,更多的pythoninc方法可以做你想要做的就是改变sys.stdout.write方法。遵循一个实现示例:

def make_write_flusher(f):
    orig = f.write
    def new_write(data):
        orig(data)
        f.flush()
    f.write = new_write

import sys
make_write_flusher(sys.stdout)
print("TEST")

A final consideration is that if you call super in your original implementation that fix the issue but the real think is that you don't really use the wrapper and both of following implementations give the same result. In Python interface doesn't really mater what is important if a attribute/methods is present and what is when you use it.

最后一个考虑因素是,如果你在原始实现中调用super来修复问题,但真正的想法是你没有真正使用包装器,并且以下两个实现都给出了相同的结果。在Python中,如果存在属性/方法以及使用它时的内容,那么接口并不重要。

class flushfile(io.TextIOWrapper):
    def __init__(self, f):
        super(flushfile,self).__init__(f)
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

class flushfile():
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
    def flush(self):
        self.f.flush()

#1


2  

You must add flush() method in your wrapper:

您必须在包装器中添加flush()方法:

class flushfile(io.TextIOWrapper):
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
    def flush(self):
        self.f.flush()

A simple test is:

一个简单的测试是:

import sys
sys.stdout = flushfile(sys.stdout)
print("TEST")

Without flush() you will got the error when script dead and try to call flush() of new sys.stdout.

如果没有flush(),脚本死机时会出现错误,并尝试调用新sys.stdout的flush()。

Anyway with the original version if you recover stdout before exit you can have the same result:

无论如何,如果你在退出之前恢复stdout,你可以得到相同的结果:

import sys
orig = sys.stdout
sys.stdout = flushfile(sys.stdout)
print("TEST")
sys.stdout = orig

EDIT

Maybe you don't need to wrapper for file object but just a new write() method. Python is first a functional programming language and a more pythoninc way to do what you want to do is change sys.stdout.write method. Follow an implementation example:

也许你不需要为文件对象包装,而只需要一个新的write()方法。 Python首先是一种函数式编程语言,更多的pythoninc方法可以做你想要做的就是改变sys.stdout.write方法。遵循一个实现示例:

def make_write_flusher(f):
    orig = f.write
    def new_write(data):
        orig(data)
        f.flush()
    f.write = new_write

import sys
make_write_flusher(sys.stdout)
print("TEST")

A final consideration is that if you call super in your original implementation that fix the issue but the real think is that you don't really use the wrapper and both of following implementations give the same result. In Python interface doesn't really mater what is important if a attribute/methods is present and what is when you use it.

最后一个考虑因素是,如果你在原始实现中调用super来修复问题,但真正的想法是你没有真正使用包装器,并且以下两个实现都给出了相同的结果。在Python中,如果存在属性/方法以及使用它时的内容,那么接口并不重要。

class flushfile(io.TextIOWrapper):
    def __init__(self, f):
        super(flushfile,self).__init__(f)
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()

class flushfile():
    def __init__(self, f):
        self.f = f
    def write(self, x):
        self.f.write(x)
        self.f.flush()
    def flush(self):
        self.f.flush()