gpt4 book ai didi

python - 为什么一个文件对象刷新,而另一个不刷新?

转载 作者:太空狗 更新时间:2023-10-30 02:12:55 25 4
gpt4 key购买 nike

我想要一个在写入数据时直接刷新到文件的文件对象,并这样写:

class FlushingFileObject(file):
def write(self,*args,**kwargs):
return_val= file.write(self,*args,**kwargs)
self.flush()
return return_val

def writelines(self,*args,**kwargs):
return_val= file.writelines(self,*args,**kwargs)
self.flush()
return return_val

但有趣的是,当我写入时它不会刷新,所以我尝试了一些方法,包括:

class FlushingFileObject(object):
def __init__(self,*args,**kwargs):
self.file_object= file(*args,**kwargs)

def __getattr__(self, item):
return getattr(self.file_object,item)

def write(self,*args,**kwargs):
return_val= self.file_object.write(*args,**kwargs)
self.file_object.flush()
return return_val

def writelines(self,*args,**kwargs):
return_val= self.file_object.writelines(*args,**kwargs)
self.file_object.flush()
return return_val

冲洗。

为什么子类化 file 在此实例中不起作用?

最佳答案

好问题。

发生这种情况是因为 Python 通过绕过 Python 级别的 write 方法并调用 fputs< 优化了对 file 对象的 write 调用直接。

要查看实际效果,请考虑:

$ cat file_subclass.py
import sys
class FileSubclass(file):
def write(self, *a, **kw):
raise Exception("write called!")
writelines = write
sys.stdout = FileSubclass("/dev/null", "w")
print "foo"
sys.stderr.write("print succeeded!\n")
$ python print_magic.py
print succeeded!

write 方法从未被调用!

现在,当对象不是 file 的子类时,事情会按预期工作:

$ cat object_subclass.py
import sys
class ObjectSubclass(object):
def __init__(self):
pass
def write(self, *a, **kw):
raise Exception("write called!")
writelines = write
sys.stdout = ObjectSubclass()
print "foo"
sys.stderr.write("print succeeded!\n")
$ python object_subclass.py
Traceback (most recent call last):
File "x.py", line 13, in <module>
print "foo"
File "x.py", line 8, in write
raise Exception("write called!")
Exception: write called!

仔细研究一下 Python 源代码,罪魁祸首似乎是 PyFile_WriteString 函数,由 print 语句调用,它检查是否正在写入对象to 是 file 的实例,如果是,则绕过该对象的方法并直接调用 fputs:

int
PyFile_WriteString(const char *s, PyObject *f)
{

if (f == NULL) {
/* … snip … */
}
else if (PyFile_Check(f)) { //-- `isinstance(f, file)`
PyFileObject *fobj = (PyFileObject *) f;
FILE *fp = PyFile_AsFile(f);
if (fp == NULL) {
err_closed();
return -1;
}
FILE_BEGIN_ALLOW_THREADS(fobj)
fputs(s, fp); //-- fputs, bypassing the Python object entirely
FILE_END_ALLOW_THREADS(fobj)
return 0;
}
else if (!PyErr_Occurred()) {
PyObject *v = PyString_FromString(s);
int err;
if (v == NULL)
return -1;
err = PyFile_WriteObject(v, f, Py_PRINT_RAW);
Py_DECREF(v);
return err;
}
else
return -1;
}

关于python - 为什么一个文件对象刷新,而另一个不刷新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12627297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com