Noob Q: subclassing or wrapping file class

2009-09-16 Thread kj


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

2009-09-16 Thread Steven D'Aprano
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

2009-09-16 Thread kj
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

2009-09-16 Thread Terry Reedy

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

2009-09-16 Thread Steven D'Aprano
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