Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Can I inherit member variables?

Reply
Thread Tools

Can I inherit member variables?

 
 
lm401@cam.ac.uk
Guest
Posts: n/a
 
      09-21-2006
I'm trying to work with the following idea:

class animal:
def __init__(self, weight, colour):
self.weight = weight
self.colour = colour


class bird(animal):
def __init__(self, wingspan):
self.wingspan = wingspan
print self.weight, self.colour, self.wingspan

class fish(animal):
def __init__(self, length):
self.length = length
print self.weight, self.colour, self.length


So basically I have a base class (animal) that has certain attributes.
When animal is inherited by a specific instance, further attributes are
added, but I need to have access to the original attributes (weight,
colour). When I run my code from within the derived class, self.weight
and self.colour are not inherited (although methods are inherited as I
would have expected).

It seems from reading the newsgroups that a solution might be to
declare weight and colour as global variables in the class animal:

class animal:
pass

myanimal = animal()
myanimal.weight = 4
myanimal.colour = 'blue'

But this is not exactly what I want to do.

I'm not very experienced with OOP techniques, so perhaps what I'm
trying to do is not sensible. Does Python differ with regard to
inheritance of member variables from C++ and Java?

Thanks for any help,



Lorcan.

 
Reply With Quote
 
 
 
 
Benjamin Niemann
Guest
Posts: n/a
 
      09-21-2006
Hello,

wrote:

> I'm trying to work with the following idea:
>
> class animal:
> def __init__(self, weight, colour):
> self.weight = weight
> self.colour = colour
>
>
> class bird(animal):
> def __init__(self, wingspan):
> self.wingspan = wingspan
> print self.weight, self.colour, self.wingspan
>
> class fish(animal):
> def __init__(self, length):
> self.length = length
> print self.weight, self.colour, self.length
>
>
> So basically I have a base class (animal) that has certain attributes.
> When animal is inherited by a specific instance, further attributes are
> added, but I need to have access to the original attributes (weight,
> colour). When I run my code from within the derived class, self.weight
> and self.colour are not inherited (although methods are inherited as I
> would have expected).


You'll have to invoke the __init__ method of the superclass, this is not
done implicitly. And you probably want to add the weight and colour
attributes to your subclass in order to pass these to the animal
constructor.

class fish(animal):
def __init__(self, length, weight, colour):
animal.__init__(self, weight, colour)
self.length = length
print self.weight, self.colour, self.length


HTH

--
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://pink.odahoda.de/
 
Reply With Quote
 
 
 
 
MonkeeSage
Guest
Posts: n/a
 
      09-21-2006

l...@cam.ac.uk wrote:
> When I run my code from within the derived class, self.weight
> and self.colour are not inherited (although methods are inherited as I
> would have expected).


Animal is never initialized and you're not passing weight and color
into it anyway. You need something like:

class animal: # (object): # <- new-style class
def __init__(self, weight, colour):
self.weight = weight
self.colour = colour

class bird(animal):
def __init__(self, weight, color, wingspan):
#super(bird, self).__init__(weight, color) # <- new-style init
animal.__init__(self, weight, color) # <- old-style init
self.wingspan = wingspan
print self.weight, self.colour, self.wingspan

class fish(animal):
def __init__(self, weight, color, length):
#super(fish, self).__init__(weight, color)
animal.__init__(self, weight, color)
self.length = length
print self.weight, self.colour, self.length

HTH,
Jordan

 
Reply With Quote
 
LorcanM
Guest
Posts: n/a
 
      09-21-2006
Thanks for the reply.

I think there's a basic misunderstanding about the nature of
inheritance on my side.

What I want to do is instantiate the sub class (derived class) from
within the animal class. I then expect the sub class to have inherited
some basic properties that it knows it has (weight, colour). If I can
expand the example I gave previously to try to make this a little
clearer:

class animal:
def __init__(self, weight, colour):
self.weight = weight
self.colour = colour

def describeMyself(self, type, measurement):
if type == 'bird':
myanimal = bird(measurement)
elif type == 'fish':
myanimal = fish(measurement)

class bird(animal):
def __init__(self, wingspan):
self.wingspan = wingspan
print "I'm a bird, weight %s, colour %s, wingspan %s" %
(self.weight, self.colour, self.wingspan)

class fish(animal):
def __init__(self, length):
self.length = length
print "I'm a fish, weight %s, colour %s, length %s" % (self.weight,
self.colour, self.length)


It seems from what you say that the attributes (member variables) will
have to be passed forward explicitly like any other function call. This
of course is sensible, 'bird' or 'fish' are not tied to a specific
instance of 'animal' when they are instantiated.

Thanks for the help,


Lorcan.


Benjamin Niemann wrote:


> You'll have to invoke the __init__ method of the superclass, this is not
> done implicitly. And you probably want to add the weight and colour
> attributes to your subclass in order to pass these to the animal
> constructor.
>
> class fish(animal):
> def __init__(self, length, weight, colour):
> animal.__init__(self, weight, colour)
> self.length = length
> print self.weight, self.colour, self.length
>


 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      09-21-2006
At Thursday 21/9/2006 06:52, wrote:

>class animal:
> def __init__(self, weight, colour):
> self.weight = weight
> self.colour = colour
>
>
>class bird(animal):
> def __init__(self, wingspan):
> self.wingspan = wingspan
> print self.weight, self.colour, self.wingspan
>
>class fish(animal):
> def __init__(self, length):
> self.length = length
> print self.weight, self.colour, self.length
>
>
>So basically I have a base class (animal) that has certain attributes.
>When animal is inherited by a specific instance, further attributes are
>added, but I need to have access to the original attributes (weight,
>colour). When I run my code from within the derived class, self.weight
>and self.colour are not inherited (although methods are inherited as I
>would have expected).


You have to call the base __init__ too. If a bird is some kind of
animal, it has a weight and a colour, and you have to provide them too:

class bird(animal):
def __init__(self, weight, colour, wingspan):
animal.__init__(self, weight, colour)
self.wingspan = wingspan
print self.weight, self.colour, self.wingspan

>It seems from reading the newsgroups that a solution might be to
>declare weight and colour as global variables in the class animal:


You can declare them as class attributes inside animal; this way they
act like a default value for instance attributes.

class animal:
weight = 0
colour = ''
...

>I'm not very experienced with OOP techniques, so perhaps what I'm
>trying to do is not sensible. Does Python differ with regard to
>inheritance of member variables from C++ and Java?


They are not called "member variables" but "instance attributes".
They *are* inherited [1] but you have to set their value somewhere.
Any object can hold virtually any attribute - this is *not* usually
determined by the object's class.
Base constructors ("initializer" actually) are *not* invoked
automatically, so you must call them explicitely.

Read the Python Tutorial, it's easy and will teach you a lot of
things about the language. You can read it online at
<http://docs.python.org/tut/tut.html>

[1] kinda... remember that classes don't determine the available
attributes; class attributes are inherited, and any attribute you set
on an instance will be accessible by any method of the object, even
above in the hierarchy.



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

 
Reply With Quote
 
Gabriel Genellina
Guest
Posts: n/a
 
      09-21-2006
At Thursday 21/9/2006 07:34, LorcanM wrote:

>I think there's a basic misunderstanding about the nature of
>inheritance on my side.
>
>What I want to do is instantiate the sub class (derived class) from
>within the animal class. I then expect the sub class to have inherited
>some basic properties that it knows it has (weight, colour). If I can
>expand the example I gave previously to try to make this a little
>clearer:


As an analogy: a certain animal, a given individual, is of a kind
"from birth". You don't have an abstract, unshaped, animal, that by
some kind of magic later becomes a bird, or a mammal...
When you construct an object instance, it is of a certain type from
that precise moment, and you can't change that afterwards.
So, you construct a bird, which is a kind of animal (class
inheritance is the way of modelling that "is a kind of" relationship).

Hope it becomes clearer now.



Gabriel Genellina
Softlab SRL





__________________________________________________
Preguntá. Respondé. Descubrí.
Todo lo que querías saber, y lo que ni imaginabas,
está en Yahoo! Respuestas (Beta).
¡Probalo ya!
http://www.yahoo.com.ar/respuestas

 
Reply With Quote
 
Benjamin Niemann
Guest
Posts: n/a
 
      09-21-2006
LorcanM wrote:

> Benjamin Niemann wrote:
>
>> You'll have to invoke the __init__ method of the superclass, this is not
>> done implicitly. And you probably want to add the weight and colour
>> attributes to your subclass in order to pass these to the animal
>> constructor.
>>
>> class fish(animal):
>> def __init__(self, length, weight, colour):
>> animal.__init__(self, weight, colour)
>> self.length = length
>> print self.weight, self.colour, self.length

>
> Thanks for the reply.
>
> I think there's a basic misunderstanding about the nature of
> inheritance on my side.
>
> What I want to do is instantiate the sub class (derived class) from
> within the animal class. I then expect the sub class to have inherited
> some basic properties that it knows it has (weight, colour). If I can
> expand the example I gave previously to try to make this a little
> clearer:
>
> class animal:
> def __init__(self, weight, colour):
> self.weight = weight
> self.colour = colour
>
> def describeMyself(self, type, measurement):
> if type == 'bird':
> myanimal = bird(measurement)
> elif type == 'fish':
> myanimal = fish(measurement)
>
> class bird(animal):
> def __init__(self, wingspan):
> self.wingspan = wingspan
> print "I'm a bird, weight %s, colour %s, wingspan %s" %
> (self.weight, self.colour, self.wingspan)
>
> class fish(animal):
> def __init__(self, length):
> self.length = length
> print "I'm a fish, weight %s, colour %s, length %s" % (self.weight,
> self.colour, self.length)


Do you really want one animal instance to act both as bird and fish?
Wouldn't it be more sensible to instanciate either bird or fish (animal
being what is called an abstract class in other OOP languages)? bird and
fish would then have their own implementation of describeMyself() with
the 'print "I'm a..."' statement.

I must admit that I don't really understand what you are trying to
achieve...


--
Benjamin Niemann
Email: pink at odahoda dot de
WWW: http://pink.odahoda.de/
 
Reply With Quote
 
MonkeeSage
Guest
Posts: n/a
 
      09-21-2006
Hi Lorcan,

Mabye thinking of it like this will help: birds and fishes (I love that
word, even if it is incorrect) can _do_ all the things that all animals
have in common: eat, drink, die, reproduce, &c; but that is generic.

class animal(object):
def eat(self, food): pass
...
class bird(animal): pass
class fish(animal): pass

If you want to talk about a specific bird or fish, then you have to say
more than just that it is an animal. Now, if all animals have a weight
and a color, but not all have the same weight or color, then you want
to say that this bird or fish is an animal which is colored X and
weighes Y.

class animal(object):
def __init__(self, weight, colour):
self.weight = weight
self.colour = colour
class bird(animal): pass # __init__ from animal is called implicitly
class fish(animal): pass

Now what if a bird and a fish have other attributes that not all
animals share (or at least specialized versions)? Well then you need to
say this bird is an animal which is colored X and weighs Y, but unlike
other animals, has a wingspan or length of Z.

class animal(object):
def __init__(self, weight, colour):
self.weight = weight
self.colour = colour
class bird(animal):
# override __init__ so we can say what _this_ animal is like
def __init__(self, weight, color, wingspan):
super(bird, self).__init__(weight, color)
self.wingspan = wingspan
class fish(animal):
def __init__(self, weight, color, length):
super(fish, self).__init__(weight, color)
self.length = length

Does this make more sense?

Regards,
Jordan

 
Reply With Quote
 
LorcanM
Guest
Posts: n/a
 
      09-21-2006
Thanks a lot folks for all the help. Its a lot clearer now.

If I could summarise my original misunderstanding about inheritance:

I belived that a sub class inherited a *specific instance* of the super
class.

This is clearly not right - the misunderstanding arose as I was
instantiating the super class from within the base class. As people
have pointed out it seems strange to instantiate an 'animal' and then
only later decide that it is a 'fish' or a 'bird'. Obviously my code is
an analogy to the problem I'm tackling. What I'm doing is a bit more
abstract: I'm instantiating a 'world' (as a super class) and then
various 'worldviews' as sub-classes. The 'worldviews' must know about
various aspects of the 'world' from which they are instantiated to be
able to do what they need to do (as the 'bird' needs to know about
'weight' and 'colour' to be able to describe itself).

Passing these aspects forward to the constructor of the sub class is
the solution I've implemented and it works and looks sensible.

Thanks again to all,


Lorcan.

 
Reply With Quote
 
bearophileHUGS@lycos.com
Guest
Posts: n/a
 
      09-21-2006
MonkeeSage:

If you have multiple inheritance do you need the old style init anyway?

class Animal1(object):
def __init__(self, weight, colour):
self.weight = weight
self.colour = colour

class Animal2(object):
def __init__(self, name):
self.name = name

class Bird(Animal1, Animal2):
def __init__(self, weight, color, wingspan, name):
super(Bird, self).__init__(weight, color) # Animal1
Animal2.__init__(self, name)
self.wingspan = wingspan
print self.weight, self.colour, self.wingspan, self.name

al = Bird(12, "White", 2, "Albatross")

Bye,
bearophile

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Can a static member function access non-static member? dolphin C++ 3 12-05-2007 12:39 PM
why const member, reference member can only be initialized not assigned ww C++ 4 10-26-2007 11:22 AM
Inherit member variables? Joseph Turian C++ 1 11-26-2005 08:14 AM
Can Derived class static member access protected member from base class? Siemel Naran C++ 4 01-12-2005 06:46 PM
How would I use qsort to sort a struct with a char* member and a long member - I want to sort in order of the long member Angus Comber C Programming 7 02-05-2004 06:41 PM



Advertisments