[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Basic inheritance question

Martin Rinehart

1/5/2008 10:31:00 AM

Working on parser for my language, I see that all classes (Token,
Production, Statement, ...) have one thing in common. They all
maintain start and stop positions in the source text. So it seems
logical to have them all inherit from a base class that defines those,
but this doesn't work:

import tok

class code:
def __init__( self, start, stop ):
startLoc = start
stopLoc = stop

class token(code):
pass

x = token( tok.Loc(0, 0), tok.Loc(3, 4) )

print x.startLoc.repr(), x.stopLoc.repr()

AttributeError: token instance has no attribute 'startLoc'

1) Is my design thinking good, or hopelessly unPythonic?

2) If it's good, how do you access base class data attributes? (The
doc is rich in method access info, impoverished when it comes to other
attributes.)
17 Answers

Jeroen Ruigrok van der Werven

1/5/2008 10:38:00 AM

0

-On [20080105 11:36], MartinRinehart@gmail.com (MartinRinehart@gmail.com) wrote:
>class code:
> def __init__( self, start, stop ):
> startLoc = start
> stopLoc = stop

Shouldn't this be:

self.startLoc = start
self.stopLoc = stop

?

--
Jeroen Ruigrok van der Werven <asmodai(-at-)in-nomine.org> / asmodai
ã?¤ã?§ã?«ã?¼ã?³ ã?©ã?¦ã??ã?­ã??ã?¯ ã?´ã?¡ã?³ ã??ã?« ã?¦ã?§ã?«ã?´ã?§ã?³
http://www.in-n... | http://www.ra...
Open your Heart and push the limits...

Paul Hankin

1/5/2008 10:38:00 AM

0

On Jan 5, 10:31 am, MartinRineh...@gmail.com wrote:
> ...
> class code:
>     def __init__( self, start, stop ):
>         startLoc = start
>         stopLoc = stop
> ...

You've forgotten the explicit self.
def __init__( self, start, stop ):
self.startLoc = start
self.stopLoc = stop

--
Paul Hankin

Martin Rinehart

1/5/2008 10:41:00 AM

0



Jeroen Ruigrok van der Werven wrote:
> Shouldn't this be:
>
> self.startLoc = start
> self.stopLoc = stop

Thanks! Of course it should. Old Java habits die slowly.

Bjoern Schliessmann

1/5/2008 10:53:00 AM

0

MartinRinehart@gmail.com wrote:
> Jeroen Ruigrok van der Werven wrote:

>> self.startLoc = start
>> self.stopLoc = stop
>
> Thanks! Of course it should. Old Java habits die slowly.

That's not really a Java habit. In Java and C++, personally I like
to write

this.startLoc = start
this.stopLoc = stop

It makes much clearer what a field and what a "normal" variable is
in those languages.

Regards,


Björn

--
BOFH excuse #294:

PCMCIA slave driver

Lie Ryan

1/5/2008 6:12:00 PM

0

On Jan 5, 5:40 pm, MartinRineh...@gmail.com wrote:
> Jeroen Ruigrok van der Werven wrote:
>
> > Shouldn't this be:
>
> > self.startLoc = start
> > self.stopLoc = stop
>
> Thanks! Of course it should. Old Java habits die slowly.

No, seriously it isn't Java habits only, most other languages wouldn't
need explicit calling of class name.

Bruno Desthuilliers

1/6/2008 7:46:00 PM

0

Lie a écrit :
> On Jan 5, 5:40 pm, MartinRineh...@gmail.com wrote:
>
>>Jeroen Ruigrok van der Werven wrote:
>>
>>
>>>Shouldn't this be:
>>
>>>self.startLoc = start
>>>self.stopLoc = stop
>>
>>Thanks! Of course it should. Old Java habits die slowly.
>
>
> No, seriously it isn't Java habits only, most other languages wouldn't
> need explicit calling of class name.

Where is the "explicit calling of class name" exactly ?

Francesco Guerrieri

1/6/2008 9:48:00 PM

0

On Jan 5, 2008 11:31 AM, <MartinRinehart@gmail.com> wrote:

> import tok
>
> class code:
> def __init__( self, start, stop ):
> startLoc = start
> stopLoc = stop
>
> class token(code):
> pass
>

Apart from the missing self, remember that the __init__(...) of the
base classes is not automatically called, unless you do it explicitly
or you do not provide one in the derived class.
So for instance you could have something like

class token(code):
def __init__(self, ...):
# do the token specific initialization here
....
# Now init the base class
code.__init__(self, ....)

Or, better, you could use super
if you were using new-style classes (which you are not...), like in
the following:

class token(code):
def __init__(self, ...):
# do your initialization here
super(token, self).__init__(....)

which is much better suited to allow multiple inheritance (there has
been a discussion in these days about the MRO, look for a paper by
Michele Simionato).
Quoting Alex Martelli in Python in a nutshell (page 97):
"If you get into the habit of always coding superclass calls with
super, your classes will fit smoothly even in complicated inheritance
structures. There are no ill effects whatsoever if the inheritance
structure instead turns out to be simple, as long, of course, as
you're only using the new-style object model, as I recommend".

bye,
Francesco

Dan Bishop

1/7/2008

0

On Jan 5, 4:53 am, Bjoern Schliessmann <usenet-
mail-0306.20.chr0n...@spamgourmet.com> wrote:
> MartinRineh...@gmail.com wrote:
> > Jeroen Ruigrok van der Werven wrote:
> >> self.startLoc = start
> >> self.stopLoc = stop
>
> > Thanks! Of course it should. Old Java habits die slowly.
>
> That's not really a Java habit. In Java and C++, personally I like
> to write
>
> this.startLoc = start
> this.stopLoc = stop
>
> It makes much clearer what a field and what a "normal" variable is
> in those languages.

My employer has us use the "m_" convention.

I wonder why Bjarne made "this->" optional in the first place.

Lie Ryan

1/14/2008 6:15:00 PM

0

On Jan 7, 2:46 am, Bruno Desthuilliers
<bdesth.quelquech...@free.quelquepart.fr> wrote:
> Lie a écrit :
>
> > On Jan 5, 5:40 pm, MartinRineh...@gmail.com wrote:
>
> >>Jeroen Ruigrok van der Werven wrote:
>
> >>>Shouldn't this be:
>
> >>>self.startLoc = start
> >>>self.stopLoc = stop
>
> >>Thanks! Of course it should. Old Java habits die slowly.
>
> > No, seriously it isn't Java habits only, most other languages wouldn't
> > need explicit calling of class name.
>
> Where is the "explicit calling of class name" exactly ?

Perhaps I was a bit tired when writing that (I wouldn't understand
what I wrote if I were you)... what I meant is most other languages
doesn't usually enforce us to explicitly state the containing class
name, which in python is generally called "self". Most other languages
1) automatically assign the containing class' object in a keyword
(Java: this, VB: Me) behind the screen, and 2) automatically searches
variable name in both the local variable table and the containing
class variable table (so to refer to a class variable named var from a
method inside the class, we only need to write var, not self.var as in
python). In VB, Me is extremely rarely used, in Python, self is all
over the place. Well, there is positive and negative to both sides,
convenience in VB, and flexibility in Python.

Compare the following codes:
VB.NET:
Public Class A
Dim var
Public Function aFunction()
return var

Python:
class A:
def aFunction(self):
return self.var

Bruno Desthuilliers

1/15/2008 2:00:00 PM

0

Lie a écrit :
> On Jan 7, 2:46 am, Bruno Desthuilliers
> <bdesth.quelquech...@free.quelquepart.fr> wrote:
>> Lie a écrit :
>>
>>> On Jan 5, 5:40 pm, MartinRineh...@gmail.com wrote:
>>>> Jeroen Ruigrok van der Werven wrote:
>>>>> Shouldn't this be:
>>>>> self.startLoc = start
>>>>> self.stopLoc = stop
>>>> Thanks! Of course it should. Old Java habits die slowly.
>>> No, seriously it isn't Java habits only, most other languages wouldn't
>>> need explicit calling of class name.
>> Where is the "explicit calling of class name" exactly ?
>
> Perhaps I was a bit tired when writing that (I wouldn't understand
> what I wrote if I were you)... what I meant is most other languages
> doesn't usually enforce us to explicitly state the containing class
> name, which in python is generally called "self".

'self' (or whatever you name it) is not the "containing class name",
it's the first argument of the function - which usually happens to be
the current instance when the function is used as a method.

> Most other languages
> 1) automatically assign the containing class' object

s/containing class' object/current instance/

> in a keyword
> (Java: this, VB: Me) behind the screen,

That's not very far from what a Python method object does -
automatically assign the current instance to something. The difference
is that Python uses functions to implement methods (instead of having
two distinct contructs), so the only reliable way to "inject" the
reference to the current instance is to pass it as an argument to the
function (instead of making it pop from pure air).

There are some benefits to this solution. One of them is the ability to
dynamically assign functions as methods. So if you do have some
function taking an object as first argument, you can easily turn it into
a method.

> and 2) automatically searches
> variable name in both the local variable table and the containing
> class variable table (so to refer to a class variable named var from a
> method inside the class, we only need to write var, not self.var as in
> python).

This - as you know - cannot work well with Python's scoping rules and
dynamicity. Anyway, implicit object reference is definitively a
BadThing(tm) wrt/ readbility, specially with multiparadigm languages
(like Python or C++). Why do you think soooo many C++ shops impose the
m_something naming scheme ?

Anyway, I actually know 3 languages (4 if C# works the same) that has
this implicit 'this' (or whatever the name) 'feature', and at least 5
that don't. So I'm not sure that the "most other languages" qualifier
really applies to point 2 !-)

> In VB, Me is extremely rarely used,

I used to systematically use it - like I've always systematically used
'this' in C++ and Java.

> in Python, self is all
> over the place. Well, there is positive and negative to both sides,
> convenience in VB, and flexibility in Python.

As far as I'm concerned, there's *no* positive point in implicit object
reference, and there has never been (and before some paranoid nutcase
around accuse me of overzealous biggotry : I already held this very same
opinion years before I discovered Python).

> Compare the following codes:
> VB.NET:
> Public Class A
> Dim var
> Public Function aFunction()
> return var

Add three levels of inheritence and a couple globals and you'll find out
that readability count !-)

In any non-trivial piece of C++ code, and unless the author either used
the explicit 'this' reference or the 'm_xxx' naming convention, you'll
have hard time figuring out where a given name comes from when browsing
a function's code.