# inheritance of file type / define subclass of file type
Python 文件对象的方法对很多人来说都不能满足需求。还有文本文件的seek功能有限制,很不方便。于是就应该继承文件对象。一种简单的办法是 wrap。就是让文件对象成为新对象的属性。这样通过 self.fo.method 就可以调用原有的方法同时定义新方法,起到扩展方法的功能。
class myFO:
# a wrap of file object
def __init__(self,fname,mode='r'):
self.fo=open(fname,mode)
def blah blah blah
可是我们会觉得这样很啰嗦,read 方法只能通过 self.fo.read 来调用,不能直接 self.read,要么重新定义 read 方法;可是重新定义就没有继承的意义了。因此,本人推荐一种方法,可以直接用 self.read 来调用 self.fo.read, 而不会有危险发生。注意__setattr__会截获任意一次赋值,但是这不会有问题。
class myFO:
# a wrap of file object
def __init__(self,fname,mode='r'):
self.fo=open(fname,mode)
def __setattr__(self, attr, val):
#print('catch',attr,'when setattr')
super().__setattr__(attr,val) # or super(myFO,self)
if attr != 'fo': # make sure f.attr == f.fo.attr where attr is not fo
setattr(self.fo,attr,val)
def __getattr__(self,attr):
#print('catch',attr,'when getattr')
return getattr(self.fo,attr)
还有就是真正意义上的继承了。但没有想象中那么简单,注意语法!初始化是要用 rb 而不是 r !其实本人也没搞懂buffer,只是一样画葫芦,而且也不知道 io 和 _io 之间的区别。
import io # import _io
class myFO(io.TextIOWrapper): # (_io.TextIOWrapper)
def __init__(self, buffer):
super().__init__(buffer)
def eof(self):
'''
judge fp is at the end of file
'''
cont=self.read(1)
if cont=='':
return True
else:
pos=self.tell()
self.seek(pos-1)
return False
fo=myFO(open('test.txt','rb')) # 注意初始化,用rb # 或者 f=open('test.txt','r');fo=myFO(f.buffer), 请不要关闭f
如果用 fo=myFO(open('test.txt','r')) ,就会有如下报错
Traceback (most recent call last):
File "D:\Python\mytest\cls.py", line 81, in <module>
print(fo.read()) # 报错
TypeError: 'str' does not support the buffer interface
PyPI上能找到 filelike, fileutils。它们都和文件对象有关,提供了很多强大的方法。但是并没有实现真正的继承。还是通过wrap实现。