Bind an instance of a base to a subclass - can this be done?

L

Lou Pecora

I've been scanning Python in a Nutshell, but this seems to be either
undoable or so subtle that I don't know how to do it.

I want to subclass a base class that is returned from a Standard Library
function (particularly, subclass file which is returned from open). I
would add some extra functionality and keep the base functions, too.
But I am stuck.

E.g.

class myfile(file):
def myreadline():
#code here to return something read from file

Then do something like (I know this isn't right, I'm just trying to
convey the idea of what I would like)

mf=myfile()

mf=open("Afile","r")

s=mf.myreadline() # Use my added function

mf.close() # Use the original file function


Possible in some way? Thanks in advance for any clues.

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
 
D

Diez B. Roggisch

Lou said:
I've been scanning Python in a Nutshell, but this seems to be either
undoable or so subtle that I don't know how to do it.

I want to subclass a base class that is returned from a Standard Library
function (particularly, subclass file which is returned from open). I
would add some extra functionality and keep the base functions, too.
But I am stuck.

E.g.

class myfile(file):
def myreadline():
#code here to return something read from file

Then do something like (I know this isn't right, I'm just trying to
convey the idea of what I would like)

mf=myfile()

mf=open("Afile","r")

s=mf.myreadline() # Use my added function

mf.close() # Use the original file function


Possible in some way? Thanks in advance for any clues.

Nope, not in that way. But you might consider writing a proxy/wrapper
for an object. That looks like this (rouch sketch from head):

class FileWrapper(object):
def __init__(self, f):
self._f = f

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

def myreadline(self):
....


Then you do

f = FileWrapper(open(name, mode))


Diez
 
M

Maric Michaud

Le Mercredi 24 Mai 2006 22:04, Diez B. Roggisch a écrit :
Nope, not in that way. But you might consider writing a proxy/wrapper
for an object. That looks like this (rouch sketch from head):

class FileWrapper(object):
    def __init__(self, f):
       self._f = f

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

    def myreadline(self):
       ....
Why use a proxy when you can just inherit from the builtin file object ?

class myFile(file) :
def myreadline(self) : print 'yo'


In [20]: myFile('frwiki-20060511-abstract.xml')
Out[20]: <open file 'frwiki-20060511-abstract.xml', mode 'r' at 0xa78cc1e4>

In [21]: myFile('frwiki-20060511-abstract.xml').myreadline()
yo

In [22]:



--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 
B

Ben Cartwright

Lou said:
I want to subclass a base class that is returned from a Standard Library
function (particularly, subclass file which is returned from open). I
would add some extra functionality and keep the base functions, too.
But I am stuck.

E.g.

class myfile(file):
def myreadline():
#code here to return something read from file

Then do something like (I know this isn't right, I'm just trying to
convey the idea of what I would like)

mf=myfile()

mf=open("Afile","r")

s=mf.myreadline() # Use my added function

mf.close() # Use the original file function


Possible in some way? Thanks in advance for any clues.
This:

Is actually creating an instance of myfile, then throwing it away,
replacing it with an instance of file. There are no variable type
declarations in Python.

To accomplish what you want, simply instantiate the subclass:

You don't need to do anything tricky, like binding the instance of the
base class to a subclass. Python does actually support that, e.g.:
def f(self):
return 'base' def f(self):
return 'subclass' 'subclass'

But the above won't work for the built-in file type:
TypeError: __class__ assignment: only for heap types

Again though, just instantiate the subclass. Much cleaner.

Or if that's not an option due to the way your module will be used,
just define your custom file methods as global functions that take a
file instance as a parameter. Python doesn't force you to use OOP for
everything.

--Ben
 
D

Diez B. Roggisch

Maric said:
Le Mercredi 24 Mai 2006 22:04, Diez B. Roggisch a écrit :
Why use a proxy when you can just inherit from the builtin file object ?

To be honest - in my perception file is a function. Which it isn't, but
I see it that way :)

You are of course right, and have the better solution (unless the OP is
not in control of file creation).

Diez
 
M

Maric Michaud

Le Jeudi 25 Mai 2006 01:10, vous avez écrit :
The ratio of two durations has no meaning???
Oh, sorry, sure it has, I wanted to say "it has no meaning in timedelta
provided arithmetic".
It's a ratio (no dimension) not a duration. In that sense the expected result
should be a float, and the proposed operator will break the timedelta's
arithmetic consistence.

t, u, v <- timedeltas
t+u # valid
t / u # valid
t / u + v # invalid while all terms are valids

It's a big design flaw and I think it's the full answer to the original
question.

Le Jeudi 25 Mai 2006 02:26, Robert Kern a écrit :
Uh, no. Besides the integer division problem in your first line, keep in
mind that the .days attribute does not give you the time interval measured
in days. It gives you the number of *whole* days in the interval. The first
method will be incorrect if time_diff is not an even multiple of 1 day.
The latter will be incorrect if time_diff is not an even multiple of 7 days.
In fact i was computing the exact number of whole weeks in the delta. In
respect of that both expression are perfectly correct, but the second one
isn't clear IMO (why this "days" attribute should give me the number of
weeks ?).

This said it's not hard to figure out the correct expression of the decimal
value of weeks in deltas (discarding the microseconds which are not
relevant) :
num_weeks = (time_diff.days * 24* 3600 + time_diff.seconds) / (7.*24*3600)

If I need to do much of these in a piece of code I would probably define some
helper functions like this :

def tomicroseconds(td) :
return td.days * 24* 3600 * 10**6 +
td.seconds * 10 ** 6 + td.microseconds

def toseconds(td) : return float(tomicroseonds(td)) / 10 ** 6
tominute, tohours, todays, toweeks, etc...

and use float and int / and % operators.
This is an easy and clean implementation IMHO.

--
_____________

Maric Michaud
_____________

Aristote - www.aristote.info
3 place des tapis
69004 Lyon
Tel: +33 426 880 097
 
L

Lou Pecora

"Diez B. Roggisch said:
Lou Pecora schrieb: [cut]
Then do something like (I know this isn't right, I'm just trying to
convey the idea of what I would like)

mf=myfile()

mf=open("Afile","r")
Possible in some way? Thanks in advance for any clues.

Nope, not in that way. But you might consider writing a proxy/wrapper
for an object. That looks like this (rouch sketch from head):

class FileWrapper(object):
def __init__(self, f):
self._f = f

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

def myreadline(self):
....

Then you do

f = FileWrapper(open(name, mode))

Diez

Interesting. I have to think about this to understand if it is a
solution I can use. But, thank you for a very different angle on this.

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
 
L

Lou Pecora

Maric Michaud said:
Le Mercredi 24 Mai 2006 22:04, Diez B. Roggisch a écrit :
Nope, not in that way. But you might consider writing a proxy/wrapper
for an object. That looks like this (rouch sketch from head):

class FileWrapper(object):
    def init (self, f):
       self. f = f

    def getattr (self, name):
       return getattr(self. f, name)

    def myreadline(self):
       ....
Why use a proxy when you can just inherit from the builtin file object ?

class myFile(file) :
def myreadline(self) : print 'yo'


In [20]: myFile('frwiki-20060511-abstract.xml')
Out[20]: <open file 'frwiki-20060511-abstract.xml', mode 'r' at 0xa78cc1e4>

In [21]: myFile('frwiki-20060511-abstract.xml').myreadline()
yo

In [22]:

BINGO! This is exactly what I want. I didn't realize that I could open
using file itself instead of open. I did find this in another section
of Python in a Nutshell thanks to your suggestion.

Thank you.

And thanks to all who answered.

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
 
L

Lou Pecora

I came up with this solution for subclassing the file object and making
some easy I/O functions (much thanks to Maric Michaud for pointing me in
the right direction). My goal was to make I/O of variables easy and in
a form that I could easily visually examine the file (which I often need
to do). The code also keeps it very clear as to what is being read in
or out in a single function call.

The class (inherited from file) in file ezfile.py:

# ==== File subclass from file for EZ I/O =======================

class ezfile(file):

# ---- Write items to file ------------------
# converts items list to string first using repr fcn.
def printline(_, ls):
sls=repr(ls)
_.writelines(sls)

# ---- Scan line from file & return items --------------------
# converts scanned string to list first using eval fcn.
def scanline(_,):
sls=_.readline()
return eval(sls)


An example in a Python session:

# Define some variables
# Open a file and output the variables to it
ff=ezfile('junk','w')
ff.printline([x,i,str])
ff.close()

# Open the same file and read the values back in to other variables
The file content looks like this:

[2.3340000000000001, 7, 'Some stuff here']

easy to see what is saved to the file.

It works! Thanks, again. Comments welcome.

-- Lou Pecora (my views are my own) REMOVE THIS to email me.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top