[Tutor] Simple Question On A Method (in subclass)

Alan Gauld alan.gauld at btinternet.com
Mon Oct 24 10:40:49 CEST 2011

On 24/10/11 04:08, Chris Kavanagh wrote:

> Thanks so much for the help Alan. . .I'm not trying to beat this
> question into the ground, LOL, but let me see if I can ask it a better way.

Marc has already given a good answer, but I'll try a slightly different 
approach to the same thing.... The differences are purely philosophical :-)

> So we have {member.tell} as the last line of code. So trying to
> understand this piece of code, {member} the variable is considered an
> object?


member is an object because it is an instance of a class.
We created instances of Teacher and Student (t and s) and put them in a 
list (members) with this code:

t = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('Swaroop', 22, 75)
members = [t, s]

Thus for member in members takes each object in the list and assigns it 
to member.

We can read {for member in members} as

"Let member take on, in turn, each value in the collection members"

And making it more explicit with a while loop:

index = 0
while index < len(members):
     member = members[index]
     index += 1

 > Therefore we can combine it with a function {tell()} using dot
 > notation?? Is this correct??? I haven't seen anything but an
 > object combined with a function using dot notation.

dot notation is how we access anything that is defined inside the class 
definition. In this case there are only the __init__() and tell() 
methods but there could be data attributes too. Furthermore we can add 
data attributes to the objects by using the self parameter, as is done 
in __init__() So we end up with the instance containing the attributes 
defined at the class level (including those of its superclass) plus any 
added by the __init__() method which is called when the object is 
created (or instantiated). So for Teacher the attributes will be:

name   - from SchoolMember.__init__()
age    - ditto
salary - from Teacher.__init__()

So we could have accessed any of those for the first iteration of the 
loop because member was a Teacher instance (t) using:

member.tell, member.name, member.age, member.salary

But the last one would have broken for the second object in the list 
since it was a student, which doesn't have a salary. So when dealing 
with a list of objects we have to restrict the access via dot notation 
to those attributes that are common to all objects in the collection - 
usually the ones defined in the super class.

Python doesn't care whether the attributes we access are data or 
functions because in Python everything is an "object" (see Marc's post)
But by putting parentheses after the object name Python treats the named 
object as a function (specifically a "callable" object)

You can see this diffence at work in the interpreter if you
type this:

 >>> def f():
...   return "Called f"
 >>> print f
<function f at 0x3180c88>
 >>> print f()
Called f

See the difference the () made? Without it we print the function object 
called f. With it we print the result of calling the function f.
Thats quite a subtle concept and usually hard for beginners to grasp but 
it is a very powerful concept and you will find it being used in
more advanced programs, especially GUI development.

 >  So I'm trying to figure out how we can
> combine the variable {member} with the function {tell}. Hope this
> question makes sense to you, LOL. Thanks again.

How we combine it is done inside Python as part of the magic of classes 
and instantiation. Basically you can call any function defined inside a 
class and Python will automatically assign the first parameter of that 
function to the object instace that you are referencing at the time.

Thus when we do

for member in members:

Python recognises that first time round member refers to the object t 
which is an instanmce of Teacher. It then calls the tell() method within 
the Teacher class definition and assigns t as the self parameter.
We could write it explicitly as:

Teacher.tell(member)  # where member is t

On the second time round member is assigned to s and Python recognizes 
that s in an instance of Student. So it calls Student.tell(member) where 
member is s.

The member.tell() notation is just a convenient way for us to write it
and allows Python to do the hard work of figuring out what kind of 
object member is at any given time.

[Aside: In true OOP speak we describe the process as "sending a message 
to the object. Thus member.tell() sends the message "tell" to the object 
"member" and the OOP framework invokes the corresponding method tell() 
in the corresponding class. In some OOP languages you can use different 
names for the messages and corresponding methods but in Python they are 
the same so we just talk about calling the method.]


Alan G
Author of the Learn to Program web site

More information about the Tutor mailing list