Reading Until EOF
Ian Bicking
ianb at colorstudy.com
Tue Oct 21 14:51:13 EDT 2003
On Tuesday, October 21, 2003, at 01:27 PM, Scott Brady Drummonds wrote:
> Hi, everyone,
>
> I'm a Python novice and would love some tips on how I should perform
> the
> following task: I'd like to have my Python script read objects (using
> their
> constructors) and terminate gracefully when an EOF is encountered. My
> first
> attempt looked like this:
>
> # This is enclosed in a 'try' block
> file = open(...)
> while 1:
> # The Object constructor raises an exception for end-of-file
> object = Object(file)
> self.list = self.list + [object]
Maybe you don't want to use a constructor, maybe you want to use a
function. The function could return None when there were no more
objects to be found.
But that might not be possible, because maybe you won't know if the
file is truncated until you are part way through constructing the
object. In this case an exception probably the best way to go, i.e.:
while 1:
try:
self.list.append(Object(file))
except EOFError:
break
> However, I'm not entirely comfortable having the Object constructor
> raise an
> exception when the end-of-file is hit. Per my experience with C++,
> this
> does not qualify as "exceptional behavior". Frankly, it is accepted.
> I'd
> like to save the exceptions for true exceptions. My next guess:
No need to save exceptions -- they aren't a scarce resource. If you
are worried about ambiguity (which probably isn't problem in this case)
you can define your own exception, like:
class ObjectEOFError(EOFError): pass
class Object:
def __init__(self, file):
try:
tok = getToken(file)
except EOFError: # We expect this might happen...
raise ObjectEOFError
This can be more useful when you might get a ValueError or TypeError,
which could get generated anywhere (even though you might only want to
catch an exception created in one place).
> # This is enclosed in a 'try' block
> file = open(...)
> while object = Object(file):
> self.list = self.list + [object]
>
> With this implementation, the file reading stops both with an exception
> (raised by a parsing error, as an example) and when the Object
> constructor
> returns something that makes the while conditional fail. However,
> therein
> lies the rub: I don't know how to do this in Python.
>
> Is there a way for me to make the second implementation work? Is
> there an
> "empty" operator in Python that I could overload? Can I have a
> constructor
> return 'null'?
It's kind of a pain, but you can do that. You can use the __new__
method. Or you can use a class method, like:
class Object(object): # Remember the (object)!
def fromFile(cls, file):
try:
return cls(file)
except EOFError:
return None
fromFile = classmethod(fromFile)
Then use Object.fromFile(file), which returns None when there's an
exception. Or you can use a function which does the same (though you
seem to be construction just such a function). I always forget the
magical __new__ incantation, maybe it's something like:
class Object(object):
def __new__(cls, file):
try:
inst = object.__new__(cls, file)
except EOFError:
return None
I'm not entirely clear if that will work though -- it depends if
__init__ is called after __new__, or during object.__new__. I don't
like the __new__ method -- it's always a little magical to me -- and I
wouldn't really recommend it.
--
Ian Bicking | ianb at colorstudy.com | http://blog.ianbicking.org
More information about the Python-list
mailing list