[Tutor] Constructs
Steven D'Aprano
steve at pearwood.info
Tue Apr 8 16:39:59 CEST 2014
On Tue, Apr 08, 2014 at 11:10:57AM +0530, Santosh Kumar wrote:
> 1 #!/usr/bin/python
> 2
> 3 class shape:
> 4 def __init__(self,x,y):
> 5 self.x = x
> 6 self.y = y
> 7 description = "This shape has not been described yet"
> 8 author = "Nobody has claimed to make this shape yet"
Notice that the body of the __init__ method is indented (by two spaces
-- four is recommended) from the method header. The body ends once the
indentation returns to the previous level. So this piece of code has
three levels of indentation:
Level 0: "class shape" is not indented;
Level 1: "def __init__" is 1 indent in;
Level 2: the body of the method is 2 indents in;
Level 1: the "description" and "author" lines are outdented
from 2 back to 1.
Because "description" and "author" are indented level with the __init__
definition (NOT the body of the method, the def header) that makes them
*class attributes*. They are bound to the class itself, not the
instance, and are shared by all instances. In Java terms they would be
called "static variables".
> 9
> 10 def __init__(self,x,y,z):
> 11 self.x = x
> 12 self.y = y
> 13 self.z = z
This now overwrites the existing __init__ method with a new method, also
called __init__, that takes three arguments instead of two. Because
methods are values exactly the same as strings, floats, bools and so
forth, you can only have one method with the same name. If you wrote:
x = 1
x = 2
of course you would expect that the second assignment to x overwrites
the first assignment -- x cannot have two different values at the same
time. The same applies to methods: you cannot have __init__ set to a
method taking arguments x, y, z and a method taking arguments x, y at
the same time. The newest assignment wins.
Java methods are fixed at compile-time, so it is easy for the compiler
to decide which constructor method to call at compile-time: if there are
two arguments, call the first method, if there are three, call the
second. But Python methods are values, and can be replaced on the fly at
run-time. Python can do run-time polymorphism, but not in the same way
that you do it with Java. Instead, you should define the method with
default arguments:
def __init__(self, x, y, z=None):
self.x = x
self.y = y
if z is not None:
self.z = z
> 14 print "The values are %d,%d,%d" %(self.x,self.y,self.z)
This line is outdented relative to the body of the __init__
method, so it too is at the class scope. That means that the print
statement will be executed at class definition time. The problem is, at
class definition time, there is no instance yet, even the class doesn't
exist yet, so the reference to "self" will fail with NameError.
I think what you want is for the print to be indented one more level,
so it is inside the method:
def __init__(self,x,y,z):
self.x = x
self.y = y
self.z = z
print "The values are %d,%d,%d" % (self.x, self.y, self.z)
--
Steven
More information about the Tutor
mailing list