I want to create a ‘File’ object that returns ‘Line’ objects when the ReadLine() method is invoked instead of just strings. I also want to be able to initialize the File object with either a string containing the absolute path of a text document, or with a list of a strings, and have the resulting instance behave identically in either case. The only way that I could figure out how to do this is by wrapping a File object around either a FileDoc or a FileList object, depending on the input type. Here is an abbreviated version of the solution I have so far:
class Line(object):
def __init__(self, line, count, fpath):
self.text = line
self.count = count
self.fname = fpath.split('/')[-1]
class FileBase(object):
def __init__(self):
pass
def Open(self):
self.count = 0
def Readline(self):
pass
def Get_count(self):
return self.count
def Set_count(self, val):
self.count = val
class FileList(FileBase):
def __init__(self, lines):
self.lines = lines
self.Open()
def ReadLine(self):
self.count += 1
try:
return Line(line=self.lines[self.count - 1], count=self.count - 1, fpath='list')
except IndexError:
raise StopIteration
class FileDoc(FileBase):
def __init__(self, fpath):
self.fpath = fpath
self.Open()
def Open(self):
self.count = 0
self.file = open(self.fpath, 'r')
def ReadLine(self):
self.count += 1
return Line(line=self.file.next(), count=self.count - 1, fpath=self.fpath)
class File(FileBase):
def __init__(self, input):
if type(input) == type(''):
self.actual = FileDoc(input)
elif type(input) == type([]):
self.actual = FileList(input)
else:
raise NonRecognizedInputError
def Open(self):
self.actual.Open()
def ReadLine(self):
return self.actual.ReadLine()
def Get_count(self):
return self.actual.count
def Set_count(self, val):
self.actual.count = val
However, this seems clunky and non-Pythonic as I have to use the Get_count() and Set_count() methods to access the .count member of the File object, instead of just being able to access it directly with instance.count. Is there a more elegant solution, one which would allow me to access the .count member as a member instead of with getters and setters?
Also, for bonus points, I’m still trying to figure out the whole inheritance thing. Is there a better way to structure the relationships between the classes?
To simplify the
countproperty, use thepropertydecorator:Or if you don’t want it to be a decorator:
As for your inheritance scheme, I think it’s okay; since you’re using
Fileto hide most of the details, it shouldn’t be too hard to change it later if need be. @MannyD’s comment is a good idea for restructuring; note that, for instance,fileobjects are iterables, just like lists.As a side note,
FileLinemay be better as acollections.namedtuple(just saying):