http://openbookproject.net/thinkcs/python/english3e/classes_and_objects_I.html http://openbookproject.net/thinkcs/python/english3e/classes_and_objects_II.html
class className:
[statement-1]
.
.
[statement-N]
# OK but NOT best practice!
class Point:
pass
# instantiate an object a of type Point
a = Point()
a.x = 0
a.y = 0
print(a.x, a.y)
0 0
class Point:
"""
Point class to represent and manipulate x and y in 2D coordinates
"""
count = 0 # class variable/attribute
# constructor to customize the initial state of an object
# first argument refers to the instance being manipulated;
# it is customary to name this parameter self; but can be anything
def __init__(self, xx=0, yy=0):
"""Create a new point with given x and y coords"""
# x and y are object variables/attributes
self.x = xx
self.y = yy
Point.count += 1 # increment class variable
# destructor gets called
def __del__(self):
Point.count -= 1
# instantiate an object
p = Point()
# what is the access specifier for attributes?
print('p: x = {} and y = {}'.format(p.x, p.y))
print("Total point objects = {}".format(Point.count)) # access class variable outside class
# p.__del__() # call destructor explictly
p1 = Point(10, 100)
print("p1: x = {} and y = {}".format(p1.x, p1.y))
print("Total point objects = {}".format(Point.count))
# Run this cell few times and see the value of Point.count
# How do you fix this problem? Use __del__ destructor method.
p: x = 0 and y = 0 Total point objects = 2 p1: x = 10 and y = 100 Total point objects = 1
print("Total point objects = {}".format(Point.count))
Total point objects = 2
class Point:
"""
Point class represents and manipulates x,y coords
"""
count = 0
def __init__(self, xx=0, yy=0):
"""Create a new point with given x and y coords"""
self.x = xx
self.y = yy
Point.count += 1
def dist_from_origin(self):
import math
dist = math.sqrt(self.x**2+self.y**2)
return dist
def __str__(self):
return "({}, {})".format(self.x, self.y)
p1 = Point(2, 2)
print(p1.dist_from_origin())
2.8284271247461903
p2 = Point(3, 2)
print(p2)
p2.x = 4
p2.y = 10
print(p2)
(3, 2) (4, 10)
class Point:
"""
Point class represents and manipulates x and y coordinates
"""
count = 0
def __init__(self, xx=0, yy=0):
"""Create a new point with given x and y coords"""
self.x = xx
self.y = yy
Point.count += 1
def dist_from_origin(self):
import math
dist = math.sqrt(self.x**2+self.y**2)
return dist
def __str__(self):
return "({}, {})".format(self.x, self.y)
# use setters to set attributes
def setX(self, xx):
if isinstance(x, int) or isinstance(x, float):
self.x = int(xx)
elif isinstance(xx, str):
if xx.isnumeric():
self.x = int(xx)
def setY(self, yy):
if isinstance(x, int) or isinstance(x, float):
self.y = int(y)
elif isinstance(yy, str):
if yy.isnumeric():
self.y = int(yy)
# use getters to get attributes
def getX(self):
return self.x
def getY(self):
return self.y
def move(self, xx, yy):
self.x = xx
self.y = yy
p3 = Point()
print(p3)
p3.move(10, 20)
print(p3)
(0, 0) (10, 20)
import copy
p2 = Point(3, 4)
p3 = p2 # alias or deepcopy?
print(p2 is p3) # checks if two references refer to the same object
p4 = copy.deepcopy(p2)
print(p2 is p4)
True False
def print_point(pt):
#pt.x = 100
#pt.y = 100
print('({0}, {1})'.format(pt.getX(), pt.getY()))
p = Point(10, 10)
print_point(p)
#print(p)
print(p.getX(), p.getY())
(10, 10) 10 10
def midpoint(p1, p2):
"""Returns the midpoint of points p1 and p2"""
mx = (p1.getX() + p2.getY())/2
my = (p2.getX() + p2.getY())/2
return Point(mx, my)
p = Point(4, 6)
q = Point(6, 4)
r = midpoint(p, q)
print_point(r) # better way to do this: use __str__() special method
print(r)
(4.0, 5.0) (4.0, 5.0)
exercise 1: In-class demo: Design a class to represent a triangle and implement methods to calculate area and perimeter.
class Rectangle:
""" A class to manufacture rectangle objects """
def __init__(self, posn, w, h):
""" Initialize rectangle at posn, with width w, height h """
self.corner = posn
self.width = w
self.height = h
def __str__(self):
return "({0}, {1}, {2})".format(self.corner, self.width, self.height)
box = Rectangle(Point(0, 0), 100, 200)
bomb = Rectangle(Point(100, 80), 5, 10) # In my video game
print("box: ", box)
print("bomb: ", bomb)
box: ((0, 0), 100, 200) bomb: ((100, 80), 5, 10)
r1 = Rectangle(Point(1, 1), 10, 5)
r2 = copy.copy(r1)
# r1 is not r2
r1 is r2
False
# but two corners are same
r1.corner is r2.corner
True
# let's test alias by moving r1 to a different location
r1.corner.move(10, 10)
# you can see r2 is moved to that location as well
print(r1)
print(r2)
((10, 10), 10, 5) ((10, 10), 10, 5)
# fix: use deepcopy from copy module
r3 = copy.deepcopy(r1)
r1 is r3
False
print(r1, r3)
((10, 10), 10, 5) ((10, 10), 10, 5)
r1.corner.move(20, 20)
# r1 is moved but not r3
print(r1, r3)
((20, 20), 10, 5) ((10, 10), 10, 5)