I wanted a file object that flushes out straight to file as data is being written, and wrote this:
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
but interestingly it doesn’t flush as I write to it, so I tried a few things including this:
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
which does flush.
Why doesn’t subclassing file work in this instance?
Great question.
This happens because Python optimizes calls to
writeonfileobjects by bypassing the Python-levelwritemethod and callingfputsdirectly.To see this in action, consider:
The
writemethod was never called!Now, when the object isn’t a subclass of
file, things work as expected:Digging through the Python source a bit, it looks like the culprit is the
PyFile_WriteStringfunction, called by theprintstatement, which checks to see whether the object being written to is an instance offile, and if it is, bypasses the object’s methods and callsfputsdirectly: