Classes and Objects in Python – Programmer-defined types
Video Tutorial
Python has a lot of built-in data types and we have used many of those types. Now we will try to define our own data type that is called the user-defined (Programmer-defined) data type.
To understand how to create a user-defined data type, we consider an example, where we will create a new type called Point that represents a point in 2-dimensional space.
In mathematical terms, a point the coordinates of a point are written in parentheses with a comma separating the coordinates.
For example, (10, 10) represents the point with x coordinate value is 10 and y is 10 and in general (x, y) represents the point x units to the right and y units up from the origin.
There are several ways we might represent points in Python:
First, we could have stored the coordinates separately in two variables, say x and y.
Second, we could have stored the coordinates as elements in a list data structure or tuple data structure.
Third, we could have created a new type to represent points as objects.
Creating a new user-defined data type is more difficult compared to the other two options, but it has a lot of advantages.
A user-defined or programmer-defined type is also called a class. The syntax of the class definition is:
class Point: """Represents a point in 2-D space."""
The header indicates that the new class is created with the name Point. The body of the class is a string that explains
what the class is defined for. You can also add variables and methods inside a class.
To create an object also called an instance of Point, you call Point as if it were a function.
Creating a new object (instance) is called instantiation, and the object is an instance of the class.
blank = Point()
Attributes of object of a class
One can assign values to an instance using dot notation. The syntax is similar to the syntax for selecting a variable from a module, such as math.pi or string.whitespace. Here we have created two elements of an object and assigned values to the elements of an object. These elements are called attributes of objects. The state diagram that shows an object (instance) and its associated attributes are called an object diagram which is shown below.
blank.x = 3.0 blank.y = 4.0
The value of an element of an object can be displayed as shown below example. The two syntaxes are shown with and without using a format specifiers.
print ('The value of element x is: ',blank.x) print ('The value of element y is: ',blank.y)
Output
The value of element x is: 3.0 The value of element y is: 4.0
print ('The value of element x is %g \nThe value of element y is %g' % (blank.x, blank.y))
Output
The value of element x is 3 The value of element y is 4
The complete python program to create a class, instantiate, add elements to object and display the values of elements of the object.
import math class Point: """Represents a point in 2-D space.""" blank = Point() blank.x = 3.0 blank.y = 4.0 print ('(%g, %g)' % (blank.x, blank.y))
Output
(3, 4)
Python program to find the distance from the origin to the given point using Classes and Objects in Python
First, create a class named Point and create an object of the class.
Then, ad elements (coordinates) to the object and find the distance from the origin to a given point.
Formula to find the distance is: distance = sqrt((x2-x1)^2 + (y2-y1)^2). Here (x1, y1) and (x2, y2) are two points. Finally display the distance.
import math class Point: """Represents a point in 2-D space.""" blank = Point() blank.x = 3.0 blank.y = 4.0 distance = math.sqrt((0-blank.x)**2 + (0-blank.y)**2) print ('Distance is %g'%distance)
Output
Distance is 5
The same program is implemented using functions
Here print_point() function is used to print the coordinates of the point and the distance() function is used to calculate the distance between the origin and the given point.
import math def print_point(p): print('(%g, %g)' % (p.x, p.y)) def distance(q): d = math.sqrt((0-q.x)**2+(0-q.y)**2) print ('Distance is %g'% (d)) class Point: """Represents a point in 2-D space.""" blank = Point() blank.x = 3.0 blank.y = 4.0 print_point(blank) distance(blank)
Output
(3, 4) Distance is 5
Rectangles
Sometimes it is obvious what the attributes of an object should be, but other times you have to make decisions. For example, imagine you want to design a class to represent rectangles. What are the attributes you use to specify the corner of the rectangle and the size of a rectangle? assume that the rectangle is either vertical or horizontal.
There are at least two possibilities:
You can specify one corner of the rectangle (or the center) using point, the width, and the height.
You can specify two-point to represent opposite corners.
In the next, for example, one point and width and height of the rectangle are used to represent the rectangle. One corner (point) is (0, 0) and width is 100 and the height is 200.
class Point: """Represents a point in 2-D space.""" class Rectangle: """Represents a rectangle attributes: width, height, corner.""" box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0
The program demonstrates how to find the center of the rectangle – Classes and Objects in Python
User-defined functions can return objects or instances. For example, the find_center function takes a Rectangle as an argument and returns a Point that contains the coordinates of the center of the Rectangle:
class Point: """Represents a point in 2-D space.""" class Rectangle: """Represents a rectangle attributes: width, height, corner.""" box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0 def find_center(rect): p = Point() p.x = rect.corner.x + rect.width/2 p.y = rect.corner.y + rect.height/2 return p def print_point(p): print('Center is: (%g, %g)' % (p.x, p.y)) center = find_center(box) print_point(center)
Output
Center is: (50, 100)
Objects are mutable
You can change the state (values of elements) of an object by making an assignment to one or all of its attributes. For example, to change the size of a rectangle without changing its position (keeping corner at the same place), you can modify the values of width and height:
box.width = box.width + 50
box.height = box.height + 100
class Point: """Represents a point in 2-D space.""" class Rectangle: """Represents a rectangle attributes: width, height, corner.""" box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0 def grow_rectangle(rect, dwidth, dheight): rect.width += dwidth rect.height += dheight box.width = box.width + 50 box.height = box.height + 100 print ('Before Grow - width = %g and height = %g' %(box.width, box.height)) print('------------------------------------------') grow_rectangle(box, 50, 100) print ('After Grow - width = %g and height = %g' %(box.width, box.height)) print('------------------------------------------')
Output
Before Grow - width = 150 and height = 300 ------------------------------------------ After Grow - width = 200 and height = 400 ------------------------------------------
Copying Objects
Aliasing an object can make a program difficult to read because changes to an object at one place might have unexpected effects on to object at another place. It is very difficult to keep track of all the modifications to the variables that might refer to a given object. Copying an object is the best solution to aliasing. The copy library contains a function called copy that can be used to create a duplicate of any object. The example shows, how to copy one point to another.
import copy def print_point(p): print('(%g, %g)' % (p.x, p.y)) class Point: """Represents a point in 2-D space.""" p1 = Point() p1.x = 3.0 p1.y = 4.0 p2 = copy.copy(p1) print_point(p1) print_point(p2)
Output
(3, 4) (3, 4)
Both p1 and p2 points contain the same data, but they are not the same Point. The is operator indicates that p1 and p2 are not the same objects, which is what we expected. both in operator and == return False. That is because, for user-defined types, Python does not know what should be considered equivalent.
p1 == p2
Output
False
p1 is p2
Output
False
If you use the copy.copy function to create a duplicate of Rectangle, you will find that it copies the Rectangle object but not the embedded Point within it. The example shows how to copy one rectangle to another.
box2 is box returns False but, box2.corner is box.corner returns True
This type of copy is called a shallow copy because it copies the object and any references an object contains, but not the embedded objects within it.
import copy class Rectangle: """Represents a rectangle attributes: width, height, corner.""" class Point: """Represents a point in 2-D space.""" box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0 box2 = copy.copy(box)
box2 is box
Output
False
box2.corner is box.corner
Output
True
For almost all applications, we don’t want this type of copy. Fortunately, the copy library provides a function named deepcopy that copies not only the object but also the objects it refers to, and the objects they refer to, and so on. You will not be surprised to learn that this operation is called a deep copy.
import copy class Rectangle: """Represents a rectangle attributes: width, height, corner.""" class Point: """Represents a point in 2-D space.""" box = Rectangle() box.width = 100.0 box.height = 200.0 box.corner = Point() box.corner.x = 0.0 box.corner.y = 0.0 box3 = copy.deepcopy(box)
box3 is box
Output
False
box3.corner is box.corner
Output
False
Summary:
The tutorial discusses, how to use Classes and Objects in Python, deep copy, and shallow copy. If you like the tutorial share it with your friends. Like the Facebook page for regular updates and YouTube channel for video tutorials.