Reading Until EOF
Alex Martelli
aleaxit at yahoo.com
Tue Oct 21 18:13:27 EDT 2003
Scott Brady Drummonds wrote:
...
> # 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
It's a bad idea, as others have pointed out, but, sure -- as long as you
change this into something like:
while True:
object = Object(file)
if object is None: break
self.list.append(object)
or -- perhaps a bit more Pythonically, but otherwise equivalently:
def Objfromfile(): return Object(file)
self.list.extend([ object for object in iter(Objfromfile, None) ])
> "empty" operator in Python that I could overload? Can I have a
> constructor return 'null'?
I'm not sure what an "empty operator" would be. You can easily
make a function return None; use a factory function instead of the
bare ctor and you're all set (you'd do it that way in C++ too, and
there you'd have no alternative to that OR an exception).
You _CAN_ have Object.__new__ return what you want -- iff it
returns an instance of Object, that is then passed to Object.__init__.
Basically calling Object(xxx) is like calling a function that does:
def equivalent(xxx):
result = Object.__new__(Object, xxx)
if isinstance(result, Object): Object.__init__(result, xxx)
return result
but basically, for that to be used the way you want you need to do
almost all the work in Object.__new__ rather than in __init__ --
you can afford to let the latter be called only when you're fully
satisfied you'll be able to construct an Object instance just fine.
It IS a bad idea, but, if you insist, assuming that Object just
needs a field of exactly 4 bytes it reads from the file, period;
where you now have
def __init__(self, file):
self.field = file.read(4)
if len(self.field) != 4: raise EOFError
have no __init__ at all and instead a __new__:
def __new__(cls, file):
result = object.__new__(cls)
result.field = file.read(4)
if len(self.field) != 4: return None
return result
Using such exoteric techniques to avoid normal idiomatic usage
and surprise every Python-aware reader of your code IS a bad
idea. Be prepared to defend it craftily at the first code review!-)
Alex
More information about the Python-list
mailing list