|
 |
Python |
8.1 Intro to Classes
|
|
See
Introductory classes, and
Advanced classes.
See also Homework 11: Classes,
which implements a fractions class.
Classes:
The precursor of a class is the C struct and the Cobol
record as a way to hold heterogeneous (not all the same type)
data items. C can keep homogeneous data in an array. Actual classes
include functions to create the class and to process the data.
Here are stack classes in C, C++, and Java:
stacks.
In Python, you can often use a tuple or a list for simple places
where a class would be needed. A tuple where the structure is created
but not changed, and a list otherwise. Early versions of the
Python implementation were often written this way (in Python),
and the implementers later added the feature named tuples
to improve readability of these features.
If using tuples or lists doesn't suffice, here is the "poor man's"
method and rules for creating Python classes:
- Start with the __init__(self,...) constructor.
- Initialize variables that are passed to the constructor as parameters.
- Initialize other desired variables in the same constructor.
- Put "self" into each function in the class as a new first parameter.
- Add "self." to the start of each variable in the class.
- Inside the class, call a member function (say, area()) with
self.area()
- From outside the class, call a member function (say, area() again)
with instance.area()
- The identifier self is only known inside functions that
are inside a class, and nowhere else.
Um, there's a bit more to it than that.
Simple Python Examples: A very
simple progression of examples is below. Example 5 illustrates
a class variable and Example 6 a private variable.
Circle Class (various forms) |
1 |
# circle1.py:
class Circle:
def __init__(self):
self.radius = 1
c = Circle()
print "radius:", c.radius
| % python circle1.py
radius: 1
|
---|
2 |
# circle2.py:
class Circle:
def __init__(xkcd): # should use "self"
xkcd.radius = 1
c = Circle()
print "radius:", c.radius
| % python circle2.py
radius: 1
|
---|
3 |
# circle3.py:
class Circle:
def __init__(self):
self.radius = 1
def area(self):
return self.radius * self.radius * 3.14159
c = Circle()
print "c.radius:", c.radius
print "c.area():", c.area()
c.radius = 3 # can change radius from outside
print "c.radius:", c.radius
print "c.area():", c.area()
| % python circle3.py
c.radius: 1
c.area(): 3.14159
c.radius: 3
c.area(): 28.27431
|
---|
4 |
# circle4.py:
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return self.radius * self.radius * 3.14159
c = Circle(1)
print "c.radius:", c.radius
print "c.area():", c.area()
c2 = Circle(3) # second circle object, diff radius
print "c2.radius:", c2.radius
print "c2.area():", c2.area()
| % python circle4.py
c.radius: 1
c.area(): 3.14159
c2.radius: 3
c2.area(): 28.27431
|
---|
Circle with a class variable: pi |
5 |
# circle5.py:
class Circle:
pi = 3.14159 # class variable
def __init__(self, radius):
self.radius = radius
def area(self):
return self.radius * self.radius * Circle.pi
print "Circle.pi", Circle.pi
c = Circle(1)
print "c.radius:", c.radius
print "c.area():", c.area()
c2 = Circle(3) # second circle object, diff radius
print "c2.radius:", c2.radius
print "c2.area():", c2.area()
Circle.pi = 4 # can change pi from outside
print "Circle.pi", Circle.pi
print "c.radius:", c.radius
print "c.area():", c.area()
print "c2.radius:", c2.radius
print "c2.area():", c2.area()
| % python circle5.py
Circle.pi 3.14159
c.radius: 1
c.area(): 3.14159
c2.radius: 3
c2.area(): 28.27431
Circle.pi 4
c.radius: 1
c.area(): 4
c2.radius: 3
c2.area(): 36
|
---|
Circle with two private instance variables:
pi and radius |
6 |
# circle6.py:
class Circle:
def __init__(self, radius):
self.__radius = radius # private variable
self.__pi = 3.14159 # private variable
def area(self):
return self.__radius * self.__radius * self.__pi
c = Circle(1)
print "c.area():", c.area()
c2 = Circle(3)
print "c2.area():", c2.area()
print "c.__radius:", c.__radius # error
| % python circle6.py
c.area(): 3.14159
c2.area(): 28.27431
c.__radius:
Traceback (most recent call last):
File "circle.py", line 13, in
print "c.__radius", c.__radius
AttributeError: Circle instance has
no attribute '__radius'
|
---|
Types of variables and where they can be used:
So far we've seen several types of variables associated with
a class:
- Instance variables: These are variables associated
with a specific instance of a class. In the first 5 examples
above, radius is an example of an instance variable. Inside
an instance of Circle, it must be referred to by self.radius.
Outside any reference must have the form instance.radius.
For example, given c = Circle(3), we must write c.radius
outside Circle.
Inside a class like Circle, an instance variable like
radius can only appear in the form self.radius
and can only appear inside a function that has self as its
first parameter.
- Class variables: These belong to the class, not
to an instance of a class. These must created by an assignment
in the class body, and not in the __init__ function.
(See pi in example 5 above.)
- Private Instance variables:
These must start with "__", but otherwise like instance variables.
They cannot be accessed or changed from outside the class.
(See __pi and __radius in example 6 above.)
Class Variable pi |
# circle_test.py
class Circle:
pi = 3.14159 # class variable
def __init__(self, radius):
# pi = 3.14159 # pi CANNOT be here
self.radius = radius
# pi = 3.14159 could be here instead
def area(self):
# pi = 3.14159 # pi CANNOT be here
return self.radius * self.radius * Circle.pi
# pi = 3.14159 could be here instead
print "Circle.pi:", Circle.pi
Circle.pi = 4
print "Circle.pi:", Circle.pi
c = Circle(3)
print "c.radius:", c.radius
print "c.area():", c.area()
Circle.pi = 3.14
print "Circle.pi:", Circle.pi
print "c.area():", c.area()
c2 = Circle(1)
print "Circle.pi:", Circle.pi
print "c2.area():", c2.area()
| % python circle1.py
Circle.pi: 3.14159
Circle.pi: 4
c.radius: 3
c.area(): 36
Circle.pi: 3.14
c.area(): 28.26
Circle.pi: 3.14
c2.area(): 3.14
|
Instance Variable pi |
# circle_test2.py
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
self.pi = 3.14159
return self.radius * self.radius * self.pi
# self.pi = 3.14159 # name 'self' is not defined
c = Circle(4)
print "c.radius", c.radius
# print "c.pi:", c.pi # ERROR, c has no attribute 'pi'
print "c.area():", c.area()
c.radius = 5
print "c.radius", c.radius
print "c.area():", c.area()
| % python circle2.py
c.radius 4
c.area(): 50.26544
c.radius 5
c.area(): 78.53975
|
Instance Variable pi |
# circle_test2.py
class Circle:
def __init__(self, radius):
self.pi = 3.14159 # This works!
self.radius = radius
def area(self):
return self.radius * self.radius * self.pi
c = Circle(4)
print "c.radius", c.radius
print "c.pi:", c.pi # This works!
print "c.area():", c.area()
c.radius = 5
print "c.radius", c.radius
print "c.area():", c.area()
| % python circle2.py
c.radius 4
c.pi: 3.14159 <--This works!
c.area(): 50.26544
c.radius 5
c.area(): 78.53975
|
A Python Stack
This example came from
Python Data Structures, a good online source of more advanced
Python programs.
|