[Tutor] deriving class from file to handle input line numbers?
Duncan Gibson
duncan at thermal.esa.int
Tue Aug 16 11:18:51 CEST 2005
I was sure that this must be a frequently asked [homework?] question,
but trying to search for 'file open line number' didn't throw up the
sort of answers I was looking for, so here goes...
I regularly write parsers for simple input files, and I need to give
helpful error messages if the input is invalid. The three most helpful
pieces on information are file name, line number and line content. Of
course I can use a global variable to track how many times f.readline()
is called, but I was wondering whether there is a more OO or Python
way of encapsulating this within a class derived from file.
What I have below is the minimal interface that I could come up with,
but it is a file adaptor rather than a derived class, and it doesn't
seem quite clean to me, because I have to open the file externally
and then pass the file object into the constructor.
Is there a better way of doing it, or am I chasing rainbows?
Cheers
Duncan
class LineCountedInputFile(object):
"""
add input line count to minimal input File interface
The file must be opened externally, and then passed into the
constructor. All access should occur through the readLine method,
and not using normal File methods on the external file variable,
otherwise things will get out of sync and strange things could
happen, including incorrect line number.
"""
__slots__ = (
'_inputFile',
'_lineNumber')
def __init__(self, inputFile):
"""
create a LineCountedInputFile adaptor object
:param inputFile: existing File object already open for reading only
:type inputFile: `File`
"""
assert isinstance(inputFile, file)
assert not inputFile.closed and inputFile.mode == 'r'
self._inputFile = inputFile
self._lineNumber = 0
#----------------------------------------------------------------------
def readLine(self):
"""
call file.readline(), strip excess whitespace, increment line number
:return: next line of text from file minus excess whitespace, or
None at end-of-file
:rtype: str
"""
line = self._inputFile.readline()
if len(line) == 0:
return None
self._lineNumber += 1
return line.strip()
#----------------------------------------------------------------------
def _get_fileName(self):
return self._inputFile.name
fileName = property(_get_fileName, None, None, """(read-only)""")
#----------------------------------------------------------------------
def _get_lineNumber(self):
return self._lineNumber
lineNumber = property(_get_lineNumber, None, None, """(read-only)""")
More information about the Tutor
mailing list