Upload
louise-chapman
View
214
Download
0
Embed Size (px)
Citation preview
Classes 2
COMPSCI 105 S2 2015Principles of Computer Science
COMPSCI 1052
Exercise Define a class that will be used to represent a
square with a given side length. Your class should include a constructor that will
allow the square to be used as follows:
Add a method to the class to calculate the perimeter of the square. The following code shows how the method may be used.
from Geometry import Square
side = 10s = Square(side)
print(s.perimeter())
Lecture05
40
COMPSCI 1053
Write a class to represent fractions in Python create a fraction add subtract multiply divide text representation
Example: Fractions
½numeratordenominator
Lecture05
COMPSCI 1054
Model of objects in memory
methods
state
num:
den:
7
8
methods
state
num:
den:
3
4
methods
state
num:
den:
1
2
xy
z
from Fraction import Fraction
x = Fraction(1,2)y = Fraction(3,4)z = Fraction(7,8)
Lecture05
COMPSCI 1055
All classes must have a constructor The constructor for a Fraction should store the
numerator and the denominator
So far, we can create a Fraction
Constructor
class Fraction: def __init__(self, top, bottom): self.num = top #numerator self.den = bottom #denominator
Lecture05
>>> x = Fraction(3, 4)>>> x.num3>>> x.den4
COMPSCI 1056
We can access and changing the state variables directly
Direct access of a data field in an object is not a good practice. The data may be tempered with, e.g., the
denominator should never be 0, but it may be mistakenly set.
The class becomes difficult to maintain and vulnerable to bugs, e.g., a change to the type of a data field in the class effects other program that uses the class.
Using the Fraction class
>>> x.num3>>> x.den -= 4>>> x.den0
Lecture05
COMPSCI 1057
To prevent direct modification of data fields, don’t let the client (user) directly access the data fields of an object.
This is known as data hiding, which can be done by defining private data fields in a class.
In Python, the private data fields are defined with two leading underscores.
You can also define a private method named with two leading underscores.
Hiding the data fields
Lecture05
class Fraction: def __init__(self, top, bottom): self.__num = top #numerator self.__den = bottom #denominator
COMPSCI 1058
Private data fields (or methods) can be accessed within in a class, but they can not be accessed outside the class.
To make a private data field accessible for the client, provide a get method to return its value.
To enable a private data field to be modifiable, provide a set method to set a new value.
Accessing private data fields
Lecture05
>>> x= Fraction(3,4)>>> x.__numTraceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'Fraction' object has no attribute '__num'>>>
COMPSCI 1059
A get method is referred to as an accessor method.
A set method is referred to as a mutator method.
Accessing the private data fields through accessor and mutator methods.
Accessor and mutator methods
Lecture05
def getNumerator(self): return self.__num
def SetNumerator(self, top): self.__num = top
>>> x = Fraction(3,4)>>> x.getNumerator()3>>> x.setNumerator(10)>>> x.getNumerator()10
COMPSCI 10510
Overriding default behaviour All classes have a number of methods provided
by default, e.g. methods to do with representing the output format of
the object methods to do with comparing two objects methods to do with computation between objects,
…… Since default behaviour is not always very useful
and accurate, we should write our own versions of those methods.
Lecture05
>>> x<__main__.Fraction object at 0x10191e3c8>>>> y = Fraction(1,4)>>> print(y)<__main__.Fraction object at 0x10191e630>>>> z = Fraction(1,4)>>> y == zFalse
COMPSCI 10511
Often we want to use a string that combines literal text and information from variables Example:
We can use string formatting to perform this task Use curly braces within the string to signify a variable
to be replaced
We can put the argument position in the curly braces
Aside: Use of string formatting syntax
name = 'Andrew'greeting = 'Hello ' + name + '. How are you?'
my_name = 'Andrew'greeting = 'Hello {name}. How are you?'.format(name = my_name)
first = 'Andrew’last = 'Luxton-Reilly'greeting = 'Hello {0} {1}!'.format(first, last)
Lecture05
COMPSCI 10512
The __repr__ method produces an string that unambiguously describes the object All classes should have a __repr__ function
implemented Ideally, the representation could be used to create the
object For example, a fraction created using Fraction(2, 3) should
have a __repr__ method that returned 'Fraction(2, 3)'
Using the object
The __repr__ method
class Fraction:def __init__(self, top, bottom): self.__num = top
self.__den = bottom def __repr__(self): return 'Fraction({0}, {1})'.format(self.__num, self.__den)
>>> x = Fraction(2, 3)>>> x Fraction(2, 3)
Lecture05
COMPSCI 10513
With the __repr__ method defined in the class, it produces:
Without the __repr__ method
>>> x = Fraction(2, 3)>>> x>>> <__main__.Fraction object at 0x02762290>)
class Fraction: def __init__(self, top, bottom): self.__num = top self.__den = bottom
Lecture05
def __repr__(self): return 'Fraction({0}, {1})'.format(self.__num, self.__den)
>>> x = Fraction(2, 3)>>> x>>> Fraction(2, 3)
COMPSCI 10514
The __str__ method returns a string representing the object By default, it calls the __repr__ method The __str__ method should focus on being human
readable We should implement a version with a natural
representation:
After we have implemented the method, we can use standard Python
The __str__ method
def __str__(self): return str(self.__num) + '/' + str(self.__den)
>>> x = Fraction(3, 4)>>> print(x)>>> 3/4
Lecture05
COMPSCI 10515
With the __str__ method defined in the class, it produces:
Without the __str__ method
>>> x = Fraction(2, 3)>>> print(x)>>> <__main__.Fraction object at 0x02762290>)
class Fraction: def __init__(self, top, bottom): self.__num = top self.__den = bottom
Lecture05
def __str__(self): return str(self.__num) + '/' + str(self.__den)
>>> x = Fraction(2, 3)>>> print(x)>>> 2/3
COMPSCI 10516
Exercise Write the __repr__ method for the Square
class created earlier.
Would it be useful to implement a __str__ method?
What would you choose to produce as output from a __str__ method?
Lecture05