Reading Until EOF
Peter Otten
__peter__ at web.de
Tue Oct 21 18:37:25 EDT 2003
Scott Brady Drummonds wrote:
> 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]
>
> 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:
>
> # 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'?
In Python constructors are precious, as there can only be one. I think it's
the wrong decision to let it construct an object from a file instance. I
would suggest a factory method instead:
class Object:
def __init__(self, word):
self.word = word
def __str__(self):
return self.word
def factory(instream):
""" construct an Object from the first word of each nonwhite line
"""
for line in instream:
if line.strip():
yield Object(line.split()[0].upper())
instream = file("fromfile.py")
try:
alist = [o for o in factory(instream)]
finally:
instream.close()
print "\n".join(map(str, alist))
The factory method could still explicitly raise an Exception for a more
complex file parsing algorithm (or simply return, if you stick with the
generator as shown above, but that is a StopIteration exception in
disguise), where you might want to separate the loop and the object
generation, but your client code is cleaner anyway.
Peter
More information about the Python-list
mailing list