Noob Q: subclassing or wrapping file class
I'm trying to get the hang of Python's OO model, so I set up this conceptually simple problem of creating a new file-like class to read a certain type of file. The data in this type of file consists of multiline chunks separated by lines consisting of a single .. My first crack at it looks like this: class MyFile(): def __init__(self, f): if hasattr(f, 'next'): self.fh = f else: self.fh = file(f, 'r') def __iter__(self): return self def next(self): buf = [] for line in self.fh: if line == '.\n': break buf.append(line) if len(buf) == 0: raise StopIteration return buf For the app I have in mind, I'd like to be able to pass an open read handle as the argument to the constructor. Hence the form of __init__. This works correctly, as far as it goes. There are still many other file methods that would make sense to implement for this class and I'm wondering if there's a simple way to do it, without having to actually write a whole bunch of methods of the form def foo(self, x, y, z): return self.fh.foo(x, y, z) I thought at first that I could achieve this by overriding __getattr__: def __getattr__(self, attribute): return self.fh.__getattr__(attribute) But to my surprise this did not work too well. For example, if I use a GzipFile object as the argument to MyFile, the iterator of the resulting object works as expected, but if I attempt to access its closed attribute I get the error AttributeError: GzipFile instance has no attribute '__getattr__' And it doesn't have __getattribute__ either. (And here I'd been thinking that __getattr__ and __getattribute__ were pretty much universal... Clearly not!) Is there a standard idiom that I'm missing for doing this sort of thing? Thanks! kynn -- http://mail.python.org/mailman/listinfo/python-list
Re: Noob Q: subclassing or wrapping file class
On Wed, 16 Sep 2009 21:56:09 +, kj wrote: ... I thought at first that I could achieve this by overriding __getattr__: def __getattr__(self, attribute): return self.fh.__getattr__(attribute) But to my surprise this did not work too well. For example, if I use a GzipFile object as the argument to MyFile, the iterator of the resulting object works as expected, but if I attempt to access its closed attribute I get the error AttributeError: GzipFile instance has no attribute '__getattr__' And it doesn't have __getattribute__ either. (And here I'd been thinking that __getattr__ and __getattribute__ were pretty much universal... Clearly not!) Is there a standard idiom that I'm missing for doing this sort of thing? Instead of: x.__getattr__('name') write this: getattr(x, 'name') Also, do a search for automatic delegation python, or just look at Alex Martelli's cookbook recipe: http://code.activestate.com/recipes/52295/ -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Noob Q: subclassing or wrapping file class
In pan.2009.09.16.22.09...@remove.this.cybersource.com.au Steven D'Aprano ste...@remove.this.cybersource.com.au writes: On Wed, 16 Sep 2009 21:56:09 +, kj wrote: ... I thought at first that I could achieve this by overriding __getattr__: def __getattr__(self, attribute): return self.fh.__getattr__(attribute) But to my surprise this did not work too well. For example, if I use a GzipFile object as the argument to MyFile, the iterator of the resulting object works as expected, but if I attempt to access its closed attribute I get the error AttributeError: GzipFile instance has no attribute '__getattr__' And it doesn't have __getattribute__ either. (And here I'd been thinking that __getattr__ and __getattribute__ were pretty much universal... Clearly not!) Is there a standard idiom that I'm missing for doing this sort of thing? Instead of: x.__getattr__('name') write this: getattr(x, 'name') This did the trick. Also, do a search for automatic delegation python, or just look at Alex Martelli's cookbook recipe: http://code.activestate.com/recipes/52295/ That was instructive. Thanks! kj -- http://mail.python.org/mailman/listinfo/python-list
Re: Noob Q: subclassing or wrapping file class
kj wrote: I'm trying to get the hang of Python's OO model, so I set up this conceptually simple problem of creating a new file-like class to read a certain type of file. The data in this type of file consists of multiline chunks separated by lines consisting of a single .. My first crack at it looks like this: class MyFile(): def __init__(self, f): if hasattr(f, 'next'): self.fh = f else: self.fh = file(f, 'r') I believe open(f, 'r') does the same thing. In 3.x, 'file' is gone and you must use 'open', so you might want to start using it now. def __iter__(self): return self def next(self): buf = [] for line in self.fh: if line == '.\n': break buf.append(line) if len(buf) == 0: raise StopIteration return buf FYI, what you have written to this point is an iterator class that could be rewritten as a generator function. You might fine that an instructive exercise. Terry Jan Reedy -- http://mail.python.org/mailman/listinfo/python-list
Re: Noob Q: subclassing or wrapping file class
On Wed, 16 Sep 2009 23:06:18 +, kj wrote: Instead of: x.__getattr__('name') write this: getattr(x, 'name') This did the trick. For the record, it's fairly unusual to call double-underscore special methods directly. Any time you think you need to, it's worth a rethink. -- Steven -- http://mail.python.org/mailman/listinfo/python-list