Mailing List Archive

YAS to the "Reading line-by-line" Problem
(YAS == Yet Another Solution)

This solution introduces file-like objects which do the Right Thing(TM) at
EOF: raise EOFError (instead of returning an empty string)

----------------- cut here ------------------
class File:
'''\
File-like objects which throw EOFError on End-of-File.

Initialize with a file-like object.
'''
def __init__(self, file):
self.__file=file

def __getattr__(self, name):
if name[:4]!='read':
return getattr(self.__file, name)
return _Wrap(getattr(self.__file, name))

class _Wrap:
def __init__(self, function):
self.function=function

def __call__(self, *args, **kw):
ret=apply(self.function, args, kw)
if ret=='': raise EOFError, 'no more data in file'
return ret

def open(file, mode='r'):
'''\
return a file like object open to /file/ with mode /mode/,
which throws an EOFError on EOF
'''
import __builtin__
return File(__builtin__.open(file, mode))

def _test():
import sys
file=open('/etc/passwd')
try:
while 1:
sys.stdout.write(file.readline())
except EOFError: pass

if __name__=='__main__':
_test()
---------------------------- cut here ---------------------------

--
Moshe Zadka <mzadka@geocities.com>.
#!/usr/bin/tail -1
Just another tail hacker.
YAS to the "Reading line-by-line" Problem [ In reply to ]
Ack is raising an exception for a normally occuring event really a
_good_ idea? Generally exceptions are only used for things that
actually are error conditions, and it would seem to me that using them
as nothing more than a fancy flow-control construct is a sure path to
nasty spaghetti code.

I really do not like this idea. :)

Moshe Zadka wrote:
>
> (YAS == Yet Another Solution)
>
> This solution introduces file-like objects which do the Right Thing(TM) at
> EOF: raise EOFError (instead of returning an empty string)
>
> ----------------- cut here ------------------
> class File:
> '''\
> File-like objects which throw EOFError on End-of-File.
>
> Initialize with a file-like object.
> '''
> def __init__(self, file):
> self.__file=file
>
> def __getattr__(self, name):
> if name[:4]!='read':
> return getattr(self.__file, name)
> return _Wrap(getattr(self.__file, name))
>
> class _Wrap:
> def __init__(self, function):
> self.function=function
>
> def __call__(self, *args, **kw):
> ret=apply(self.function, args, kw)
> if ret=='': raise EOFError, 'no more data in file'
> return ret
>
> def open(file, mode='r'):
> '''\
> return a file like object open to /file/ with mode /mode/,
> which throws an EOFError on EOF
> '''
> import __builtin__
> return File(__builtin__.open(file, mode))
>
> def _test():
> import sys
> file=open('/etc/passwd')
> try:
> while 1:
> sys.stdout.write(file.readline())
> except EOFError: pass
>
> if __name__=='__main__':
> _test()
> ---------------------------- cut here ---------------------------
>
> --
> Moshe Zadka <mzadka@geocities.com>.
> #!/usr/bin/tail -1
> Just another tail hacker.

--
---------------
Jesse D. Sightler
http://www3.pair.com/jsight/

"Do not use a hatchet to remove a fly from your friend's forehead."
- Chinese Proverb
YAS to the "Reading line-by-line" Problem [ In reply to ]
"Jesse D. Sightler" <jsight@mindspring.com> writes:

> Ack is raising an exception for a normally occuring event really a
> _good_ idea? Generally exceptions are only used for things that
> actually are error conditions, and it would seem to me that using them
> as nothing more than a fancy flow-control construct is a sure path to
> nasty spaghetti code.

Well, every for loop terminates with an IndexError exception... But
yes, it does make a mockery of the name.

The performance of exceptions in Python isn't really a concern, if
you're coming from C++ where exceptions can take thousands of times
longer than normal function returns.

> I really do not like this idea. :)
>

No, me neither. Oh well, each to their own.
M
YAS to the "Reading line-by-line" Problem [ In reply to ]
On 22 Jun 99, Jesse D. Sightler wrote:

> Ack is raising an exception for a normally occuring event really a
> _good_ idea? Generally exceptions are only used for things that
> actually are error conditions, and it would seem to me that using them
> as nothing more than a fancy flow-control construct is a sure path to
> nasty spaghetti code.
>
> I really do not like this idea. :)

Hmm, I always wanted file objects to have an eof() method... I never
quite understood why it isn't there. Assuming file objects are based
on C's fopen, fclose, fread etc. functions, it puzzles me why feof
wasn't used as well.

Of course I could write another file object to do this... but it's
not a big deal, really. I just wondered. :)

--Hans Nowak (ivnowa@hvision.nl)
Homepage: http://fly.to/zephyrfalcon
YAS to the "Reading line-by-line" Problem [ In reply to ]
On Tue, 22 Jun 1999 15:09:36 -0400, Jesse D. Sightler wrote:
>Ack is raising an exception for a normally occuring event really a
>_good_ idea? Generally exceptions are only used for things that
>actually are error conditions, and it would seem to me that using them
>as nothing more than a fancy flow-control construct is a sure path to
>nasty spaghetti code.

Exceptions may be used for errors, but they're actually intended for
_exceptions_ to normal operation.

Normal operation for a function named "readline" is to return the next
char in the file and advance the file pointer. There are two exceptions
to this behavior: when the file pointer is invalid, and when it can't be
advanced. Both should be handled by exception, not by returning a special
value.

--
-William "Billy" Tanksley
Utinam logica falsa tuam philosophiam totam suffodiant!
:-: May faulty logic undermine your entire philosophy!