We'll look at two examples of class definitions. In the both
examples, we'll write a script which defines a class and then uses the
class.
Example 21.1. die.py
#!/usr/bin/env python
"""Define a Die and simulate rolling it a dozen times."""
import random
class Die(object):
"""Simulate a generic die."""
def __init__( self ):
self.sides= 6
self.roll()
def roll( self ):
"""roll() -> number
Updates the die with a random roll."""
self.value= 1+random.randrange(self.sides)
return self.value
def getValue( self ):
"""getValue() -> number
Return the last value set by roll()."""
retur self.value
def main():
d1, d2 = Die(), Die()
for n in range(12):
print d1.roll(), d2.roll()
main()
This version of the Die class
contains a doc string and three methods:
__init__, roll
and getValue.
The __init__ method, called a
constructor, is called automatically when
the object is created. We provide a body that sets two instance
variables of a Die object. It sets the
number of sides, sides to 6 and it then rolls
the die a first time to set a value.
The roll method, called a
manipulator, generates a random number,
updating the value instance variable.
The getValue method, called a
getter or an
accessor, returns the value of the value
instance variable, value. Why write this kind
of function? Why not simply use the instance variable? We'll
address this in the FAQ's at the end of this chapter.
The main function is outside the
Die class, and makes use of the class
definition. This function creates two
Die, d1 and
d2, and then rolls those two
Die a dozen times.
This is the top-level script in this file. It executes the
main function, which — in turn — then
creates Die objects.
The __init__ method can accept arguments.
This allows us to correctly initialize an object while creating it. For
example:
Example 21.2. point.py - part 1
#!/usr/bin/env python
"""Define a geometric point and a few common manipulations."""
class Point( object ):
"""A 2-D geometric point."""
def __init__( self, x, y ):
"""Create a point at (x,y)."""
self.x, self.y = x, y
def offset( self, xo, yo ):
"""Offset the point by xo parallel to the x-axis
and yo parallel to the y-axis."""
self.x += xo
self.y += yo
def offset2( self, val ):
"""Offset the point by val parallel to both axes."""
self.offset( val, val )
def __str__( self ):
"""Return a pleasant representation."""
return "(%g,%g)" % ( self.x, self.y )
This class, Point, initializes each
point object with the x and y coordinate values of the point. It
also provides a few member functions to manipulate the
point.
The __init__ method requires two
argument values. A client program would use Point( 640,
480 ) to create a Point object and
provide arguments to the __init__
method function.
The offset method requires two
argument values. This is a manipulator which changes the state
of the point. It moves the point to a new location based on the
offset values.
The offset2 method requires one
argument value. This method makes use of the
offset method. This kind of reuse
assures that both methods are perfectly consistent.
We've added a __str__ method,
which returns the string representation of the object. When we
print any object, the print statement
automatically calls the str built-in
function. The str function uses the
__str__ method of an object to get a
string representation of the object.
We manipulate the obj1_cornerPoint to move it a few pixels left and
up.
We access the obj1_corner object by
printing it. This will call the str
function, which will use the __str__
method to get a string representation of the
Point.
The self Variable. These examples should drive home the ubiquirty of the self
variable. Within a class, we must be sure to use
self. in front of the function names as well as
attribute names. For example, our offset2
function accepts a single value and calls the object's
offset function using self.offset( val, val
).
The self variable is so important, we'll highlight it.
The self Variable
In Python, the self qualifier is simply
required all the time.
Programmers experienced in Java or C++ may object to seeing the
explicit self. in front of all variable names and
method function names. In Java and C++, there is a
this. qualifier which is assumed by the compiler.
Sometimes this qualifier is required to disambiguate names, other
times the compiler can work out what you meant.
Some programmers complain that self is too
much typing, and use another variable name like my.
This is unusual, generally described as a bad policy, but it is not
unheard of.
An object is a namespace; it contains the attributes. We can call
the attributes instance variables to distinguish
them from global variables and free variables.
Instance Variables
Instance variables are part of an object's namespace. Within
the method functions of a class, these variables are qualified by
self.. Outside the method functions of the
class, these variables are qualified by the object's name. In
Example 21.1, “die.py”, the
main function would refer to
d1.value to get the value attribute of object
d1.
Global Variables
Global variables are pare of the special global namespace.
The global statement creates the variable name
in the global namespace instead of the local namespace. See the section called “The global Statement” for more information.
Free Variables
Within a method function, a variable that is not qualified
by self., nor marked by
global is a free variable. Python checks the
local namespace, then the global namespace for this variable. This
ambiguity is, generally, not a good idea.
Published under the terms of the Open Publication License