469,304 Members | 1,888 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,304 developers. It's quick & easy.

Subclassing file and getting around the file.__init__ rigidity

Hi all y'all,

Consider the class down below. I've implemented it just because I
needed the pushback method. Now of course the third line in __init__
doesn't work and I even understand why. My question is: is there any
way to make it work? Somebody proposed a patch for fileobject.c to
allow stuff like fp = file(fp1.fileno()) but it looks like it's been
rejected. I won't so bold as to request a change in Python. Should I
try to re-write this class in C? Although I know C I'm much to lazy to
take on the entire python API, not that it doesn't look nice.

Thanks for your help

Jan Burgy

class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self = name # DOESN'T WORK!
else:
file.__init__(self, name)
self.buffer = None

def readline(self):
if self.buffer:
i = self.buffer.find("\n")
line, self.buffer = self.buffer[:i], self.buffer[:i+1]
else:
line = file.readline(self)
return line

def pushback(self, line):
self.buffer = line + self.buffer
Jul 18 '05 #1
4 1951
Jan Burgy wrote:
Consider the class down below. I've implemented it just because I
needed the pushback method. Now of course the third line in __init__
doesn't work and I even understand why. My question is: is there any
way to make it work?
What do you mean, it doesn't work? It does precisely what it says it
does:
class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self = name # DOESN'T WORK!


This assigns the local variable self to be the value of the local
variable name. As a result of that assignment, self does not refer
anymore to the object being created, but instead, it refers to
the first parameter. The object just being created is then not
accessible anymore.

If you thought this assignment might modify the object being created
in some way: Why would you think so?

Regards,
Martin

Jul 18 '05 #2
# Untested code

class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self.__dict__.update(file.__dict__) # Kinda cctor
else:
file.__init__(self, name)
self.buffer = None

Cheers
Franz

"Jan Burgy" <jb****@hotmail.com> schrieb im Newsbeitrag
news:80**************************@posting.google.c om...
Hi all y'all,

Consider the class down below. I've implemented it just because I
needed the pushback method. Now of course the third line in __init__
doesn't work and I even understand why. My question is: is there any
way to make it work? Somebody proposed a patch for fileobject.c to
allow stuff like fp = file(fp1.fileno()) but it looks like it's been
rejected. I won't so bold as to request a change in Python. Should I
try to re-write this class in C? Although I know C I'm much to lazy to
take on the entire python API, not that it doesn't look nice.

Thanks for your help

Jan Burgy

class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self = name # DOESN'T WORK!
else:
file.__init__(self, name)
self.buffer = None

def readline(self):
if self.buffer:
i = self.buffer.find("\n")
line, self.buffer = self.buffer[:i], self.buffer[:i+1]
else:
line = file.readline(self)
return line

def pushback(self, line):
self.buffer = line + self.buffer

Jul 18 '05 #3
Hi Franz,

your idea is exactly the type of stuff I was thinking of.
Unfortunately it doesn't work... Does anybody see what we're doing
wrong?

Thanks to all

Jan Burgy

"F. GEIGER" <fg*****@datec.at> wrote in message news:<c4**********@newshispeed.ch>...
# Untested code

class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self.__dict__.update(file.__dict__) # Kinda cctor
else:
file.__init__(self, name)
self.buffer = None

Cheers
Franz

"Jan Burgy" <jb****@hotmail.com> schrieb im Newsbeitrag
news:80**************************@posting.google.c om...
Hi all y'all,

Consider the class down below. I've implemented it just because I
needed the pushback method. Now of course the third line in __init__
doesn't work and I even understand why. My question is: is there any
way to make it work? Somebody proposed a patch for fileobject.c to
allow stuff like fp = file(fp1.fileno()) but it looks like it's been
rejected. I won't so bold as to request a change in Python. Should I
try to re-write this class in C? Although I know C I'm much to lazy to
take on the entire python API, not that it doesn't look nice.

Thanks for your help

Jan Burgy

class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self = name # DOESN'T WORK!
else:
file.__init__(self, name)
self.buffer = None

def readline(self):
if self.buffer:
i = self.buffer.find("\n")
line, self.buffer = self.buffer[:i], self.buffer[:i+1]
else:
line = file.readline(self)
return line

def pushback(self, line):
self.buffer = line + self.buffer

Jul 18 '05 #4
Jan Burgy wrote:
Hi all y'all,

Consider the class down below. I've implemented it just because I
needed the pushback method. Now of course the third line in __init__
doesn't work and I even understand why. My question is: is there any
way to make it work? Somebody proposed a patch for fileobject.c to
allow stuff like fp = file(fp1.fileno()) but it looks like it's been
rejected. I won't so bold as to request a change in Python. Should I
try to re-write this class in C? Although I know C I'm much to lazy to
take on the entire python API, not that it doesn't look nice.

Thanks for your help

Jan Burgy

class BufferedFile(file):

def __init__(self, name):
if type(name) == file:
self = name # DOESN'T WORK!
else:
file.__init__(self, name)
self.buffer = None

def readline(self):
if self.buffer:
i = self.buffer.find("\n")
line, self.buffer = self.buffer[:i], self.buffer[:i+1]
else:
line = file.readline(self)
return line

def pushback(self, line):
self.buffer = line + self.buffer


Here's a way to force it by using a wrapper instead of a subclass:

class BufferedFile(object):
def __init__(self, name, *more):
if isinstance(name, basestring):
self.fo = file(name, *more)
else:
self.fo = name
assert len(more) == 0
self.buffer = []

def readline(self):
if self.buffer:
return self.buffer.pop()
return self.fo.readline()

def __iter__(self):
return self

def next(self):
result = self.readline()
if not result:
raise StopIteration
return result

def pushback(self, line):
self.buffer.append(line)

def __getattr__(self, name):
return getattr(self.fo, name)

Unfortunately it grew clumsier than I originaly expected because of the
duplicated interface (next() and readline() for essentially the same
thing). Personally, I would recommend using the subclass approach and drop
the requirement of accepting a file object as an __init__() parameter.
Still the above has the advantage of working with "real files" and StringIO
objects alike (not tested, so don't blame me).
Peter

Jul 18 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Greg Krohn | last post: by
6 posts views Thread by Uwe Mayer | last post: by
4 posts views Thread by GrelEns | last post: by
2 posts views Thread by Fuzzyman | last post: by
2 posts views Thread by BJörn Lindqvist | last post: by
3 posts views Thread by Peter Olsen | last post: by
3 posts views Thread by jbauer | last post: by
6 posts views Thread by Steven D'Aprano | last post: by
3 posts views Thread by Mark E. Fenner | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by zhoujie | last post: by
reply views Thread by suresh191 | last post: by
reply views Thread by harlem98 | last post: by
1 post views Thread by Geralt96 | last post: by
reply views Thread by harlem98 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.