Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
19 views

Classes and Objects 2

This document discusses classes and objects in Python. It introduces a Point class to represent mathematical points with x and y coordinates. Instances of the Point class are created, and dot notation is used to access attributes of instances. The document also discusses defining a Rectangle class with width and height attributes, and embedding a Point instance to represent the rectangle's corner. Functions can take instances as arguments and return new instances.

Uploaded by

Jatin Verma
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Classes and Objects 2

This document discusses classes and objects in Python. It introduces a Point class to represent mathematical points with x and y coordinates. Instances of the Point class are created, and dot notation is used to access attributes of instances. The document also discusses defining a Rectangle class with width and height attributes, and embedding a Point instance to represent the rectangle's corner. Functions can take instances as arguments and return new instances.

Uploaded by

Jatin Verma
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

in

y.
Classes and objects

ud
st
ty
si
er
iv
un
User-defined compound types
Consider the concept of a mathematical point. For example, (0; 0)
represents the origin, and (x; y) represents the point x units to
the right and y units up from the origin.

in
A natural way to represent a point in Python is with two floating-

y.
point values.

ud
How to group these two values into a compound

st
ty
object?
si
er
The quick and dirty solution is to use a list or tuple, and for some
iv
applications that might be the best choice.
un

An alternative is to define a new user-defined compound type,


also called a class.
Definition of class
A class definition looks like this:

in
class Point:

y.
ud
Pass

st
Class definitions can appear anywhere in a program, but

ty
they are usually near the beginning (after the import
si
er
statements).
iv
un

This definition creates a new class called Point. The pass


statement has no effect; it is only necessary because a
compound statement must have something in its body.
By creating the Point class, we created a new type, also
called Point. The members of this type are called
instances of the type or objects. Creating a new
instance is called instantiation.

in
y.
ud
To instantiate a Point object, we call a function named

st
Point:

ty
blank = Point() si
er
iv
The variable blank is assigned a reference to a new
un

Point object. A function like Point that creates new


objects is called a constructor.
Attributes
We can add new data to an instance using dot notation:

in
>>> blank.x = 3.0

y.
ud
>>> blank.y = 4.0

st
ty
si
In this case, though, we are selecting a data item from
er
an instance. These named items are called attributes.
iv
un

The variable blank refers to a Point object, which


contains two attributes. Each attribute refers to a
floating-point number.
We can read the value of an attribute using the same
syntax:
>>> print blank.y
4.0

in
y.
>>> x = blank.x

ud
>>> print x

st
ty
3.0
si
er
There is no conflict between the variable x and the
iv

attribute x. The purpose of dot notation is to


un

identify which variable you are referring to


unambiguously.
un
iv
er
si
ty
st
ud
y.
in
un
iv
er
si
ty
st
ud
y.
in
un
iv
er
si
ty
st
ud
y.
in
un
iv
er
si
ty
st
ud
y.
in
un
iv
er
si
ty
st
ud
y.
in
Dot Notation in Expression
You can use dot notation as part of any expression, so
the following statements are legal:
print '(' + str(blank.x) + ', ' + str(blank.y) + ')'
distanceSquared = blank.x * blank.x + blank.y * blank.y

in
y.
ud
The first line outputs (3.0, 4.0); the second line

st
calculates the value 25.0.

ty
>>> print blank
si
er
<__main__.Point instance at 80f8e70>
iv
un

The result indicates that blank is an instance of the


Point class and it was defined in main . 80f8e70 is the
unique identifier for this object, written in
hexadecimal (base 16).
Instances as arguments
You can pass an instance as an argument in the usual
way. For example:

in
y.
ud
def printPoint(p):

st
print '(' + str(p.x) + ', ' + str(p.y) + ')’

ty
si
er
printPoint takes a point as an argument and displays it
iv
un

in the standard format.


If you call printPoint(blank), the output is (3.0, 4.0).
Sameness
The meaning of the word “same” seems perfectly clear
until you give it some thought, and then you realize

in
there is more to it than you expected.

y.
For example 1: if you say, “Chris and I have the same

ud
car," you mean that his car and yours are the same

st
ty
make and model, but that they are two different cars.
si
er
iv
Example 2: If you say, “Chris and I have the same
un

mother," you mean that his mother and yours are the
same person.1 So the idea of \sameness" is different
depending on the context.
To find out if two references refer to the same object,
use the == operator. For example:

>>> p1 = Point()

in
y.
>>> p1.x = 3

ud
>>> p1.y = 4

st
ty
>>> p2 = Point()
>>> p2.x = 3 si
er
iv
>>> p2.y = 4
un

>>> p1 == p2
False
Shallow Equality
If we assign p1 to p2, then the two variables are aliases
of the same object:

in
y.
>>> p2 = p1

ud
>>> p1 == p2

st
ty
True
si
er
iv

This type of equality is called shallow equality because


un

it compares only the references, not the contents of the


objects.
Deep Equality
When compare the contents of the objects, it is called
deep equality. We can write a function called

in
samePoint:

y.
ud
def samePoint(p1, p2) :

st
ty
return (p1.x == p2.x) and (p1.y == p2.y)
si
er
iv
un
Now if we create two different objects that contain the
same data, we can use samePoint to find out if they
represent the same point.

>>> p1 = Point()

in
>>> p1.x = 3

y.
ud
>>> p1.y = 4

st
>>> p2 = Point()

ty
>>> p2.x = 3
>>> p2.y = 4 si
er
>>> samePoint(p1, p2)
iv
un

True

Of course, if the two variables refer to the same object,


they have both shallow and deep equality.
Class: Rectangles
Now, we want a class to represent a rectangle, then
there are a few possibilities to specify :

in
➢center of the rectangle

y.
➢size (width and height) or

ud
➢one of the corners and the size or

st
ty
➢two opposing corners.
si
er
iv
A conventional choice is to specify the upper-left corner of
un

the rectangle and the size. Again, we'll define a new class:
class Rectangle:
pass
And instantiate it:
box = Rectangle()
box.width = 100.0

in
y.
box.height = 200.0

ud
st
ty
To specify the upper-left corner, we can embed an
si
object within an object.
er
iv
box.corner = Point()
un

box.corner.x = 0.0
box.corner.y = 0.0
un
iv
er
si
ty
st
ud
y.
in
Instances as return values
Functions can return instances. For example,
findCenter takes a Rectangle as an argument and
returns a Point that contains the coordinates of the

in
center of the Rectangle:

y.
ud
st
def findCenter(box):

ty
p = Point() si
er
iv
p.x = box.corner.x + box.width/2.0
un

p.y = box.corner.y - box.height/2.0


return p
To call this function, pass box as an argument
and assign the result to a variable:

in
>>> center = findCenter(box)

y.
ud
>>> printPoint(center)

st
(50.0, -100.0)

ty
si
er
iv
un
Objects are mutable
We can change the state of an object by making an
assignment to one of its attributes. For example, to
change the size of a rectangle without changing its

in
position, we could modify the values of width and

y.
ud
height:

st
box.width = box.width + 50

ty
box.height = box.height + 100
si
er
We could encapsulate this code in a method and
iv

generalize it to grow the rectangle by any amount:


un

def growRect(box, dwidth, dheight) :


box.width = box.width + dwidth
box.height = box.height + dheight
For example, we could create a new Rectangle
named bob and pass it to growRect:

>>> bob = Rectangle()


>>> bob.width = 100.0

in
y.
>>> bob.height = 200.0

ud
>>> bob.corner = Point()

st
ty
>>> bob.corner.x = 0.0
si
>>> bob.corner.y = 0.0
er
iv
>>> growRect(bob, 50, 100)
un

While growRect is running, the parameter box is an


alias for bob. Any changes made to box also affect
bob.
Copying
Copying an object is often an alternative to aliasing. The
copy module contains a function called copy that can
duplicate any object:

in
y.
ud
>>> import copy

st
ty
>>> p1 = Point()
>>> p1.x = 3 si
er
iv

>>> p1.y = 4
un

>>> p2 = copy.copy(p1)
>>> p1 == p2 False
>>> samePoint(p1, p2) True
Shallow Copying
To copy a simple object like a Point, which doesn't
contain any embedded objects, copy is sufficient. This

in
is called shallow copying.

y.
ud
st
For something like a Rectangle, which contains a

ty
reference to a Point, copy doesn't do quite the right
si
er
thing. It copies the reference to the Point object, so
iv

both the old Rectangle and the new one refer to a


un

single Point.
If we create a box, b1, in the usual way and then make
a copy, b2, using copy, the resulting state diagram
looks like this:

in
y.
ud
st
ty
si
er
iv
un
Deepcopy
Fortunately, the copy module contains a method named
deepcopy that copies not only the object but also any
embedded objects.

in
y.
ud
>>> b2 = copy.deepcopy(b1)

st
ty
si
er
Now b1 and b2 are completely separate objects.
iv
un
We can use deepcopy to rewrite growRect so that
instead of modifying an existing Rectangle, it creates a
new Rectangle that has the same location as the old
one but new dimensions:

in
y.
ud
def growRect(box, dwidth, dheight) :

st
import copy

ty
si
newBox = copy.deepcopy(box)
er
newBox.width = newBox.width + dwidth
iv
un

newBox.height = newBox.height + dheight


return newBox

You might also like