Below is a class definition named Shape()
. It stores the data attribute shape
which is just a string. The only member function implmented in this class is the special __str__
function which returns the string I am a shape
when called on an object instantiated from the class Shape()
.
class Shape():
def __init__(self):
self.shape = 'shape'
def __str__(self):
return "I am a " + self.shape
Now we will instantiation the class and store it in an object with the variable name s
. Then we call the print statement giving s
as and argument and it automatically runs the __str__
function and returns its result.
s = Shape()
print(s)
I am a shape
Now we will derive a class from Shape()
called Polygon()
. A Polygon()
is a Shape()
and therefore all of the functions defined in Shape()
will work on an instantiated object of Polygon()
.
We will also implement some new functions, not defined in Shape()
that can computute the perimeter of a polygon and return the number of edges.
There is also a new data attribute called side_lengths
which is initialized to None
. We can't set its exact value yet because we don't have enough information about the polygon, e.g. How many sides it has, but we need to define it in order to define compute_perimeter()
because it requires side_lengths
as an argument. Same goes for get_number_of_sides
.
class Polygon(Shape):
def __init__(self):
self.shape = 'polygon'
self.side_lengths = None
def compute_perimeter(self):
return sum(self.side_lengths)
def get_number_of_edges(self):
return len(self.side_lengths)
Now we can instantiation a Polygon()
object called p
and call print()
on it. It returns the function call from __str__
that is only defined in Shape()
because a Polygon()
is a Shape()
.
p = Polygon()
print(p)
I am a polygon
We can now derived another class from Polygon()
, this time we are specialized enough that we know a Rectange()
has 4 sides, so we can give a default value for the data attribute side_length
.
class Rectangle(Polygon):
def __init__(self):
self.shape = 'rectangle'
self.side_lengths = [1, 1, 1, 1]
And now we can call compute_perimeter()
on the object rect
that was intantiated from Rectangle()
even though we didn't define the function in the Rectangle()
class. We can do this because a Rectangle()
is a Polygon()
.
rect = Rectangle()
rect.compute_perimeter()
4
Likewise, we can derive a Triangle()
class from Polygon()
and it inherits the member functions from both Polygon()
and Shape()
. Again, a Triangle()
is a Polygon()
which is a Shape()
.
class Triangle(Polygon):
def __init__(self):
self.shape = 'triangle'
self.side_lengths = [2, 2, 2]
Examples of calling functions on the object t
instantiated from Triangle()
.
t = Triangle()
t.compute_perimeter()
6
t.get_number_of_edges()
3
print(t)
I am a triangle
Everything in Python is an object. Including the lists we've already been using. This might help you understand the .sort()
function a little better now.
x = [20, 4, 100]
x.sort()
x
[4, 20, 100]
You can also define classes that take arguments similar to the way regular functions do. Both classes and functions that are members of a class must use self
as thier first argument. After that you can use arguments as you normally would, including default arguments and variable arguments.
class Car():
def __init__(self, number_of_doors=2):
self.number_of_doors = number_of_doors
def __str__(self):
if self.number_of_doors == 2:
return "I am a coupe."
if self.number_of_doors == 4:
return "I am a sedan."
else:
return "I don't know what kind of car I am."
An example of instantiating the Car()
class with different arguments that alter it's behavior.
c = Car()
print(c)
I am a coupe.
s = Car(4)
print(s)
I am a sedan.
s = Car(3)
print(s)
I don't know what kind of car I am.