In these notes, we'll further develop our skills with object-oriented programming. Our primary focus will be on the use of magic methods to perform custom operations on our objects.
Let's implement a Vector
class. Vector
s should admit operations like addition, subtraction, and scalar multiplication. Perhaps surprisingly, Python doesn't really support this natively. For example:
# (1, 2) + (3, 4) = (4, 6)
(1, 2) + (3, 4)
(1, 2, 3, 4)
So, let's do it ourselves! We'll focus on vectors with just two dimensions. We'll soon introduce the numpy
module for working with vectors of arbitrary dimensions.
class Vector:
"""
Class for 2-dimensional vectors
Supports standard vector operations, including scalar multiplication and vector addition.
"""
def __init__(self, x, y):
self.x = x
self.y = y
def scalar_multiply(self, c):
"""
Return a Vector with components multiplied by c
"""
return(Vector(c*self.x, c*self.y))
v = Vector(1, 2)
u = v.scalar_multiply(2)
u.x, u.y
(2, 4)
So far so good, but it's not all that easy to actually view the result of the scalar multiplication. For example:
class Vector:
"""
Class for 2-dimensional vectors
Supports standard vector operations, including scalar multiplication and vector addition.
"""
def __init__(self, x, y):
self.x = x
self.y = y
def scalar_multiply(self, c):
"""
Return a Vector with components multiplied by c
"""
return(Vector(c*self.x, c*self.y))
def __str__(self):
return("Vector(" + str(self.x) + "," + str(self.y) + ")")
This motivates us to add a method for representing v
nicely as a string. The __str__
magic method does this for us.
v = Vector(1,2)
print(v)
# ---
Vector(1,2)
print(v.scalar_multiply(2))
# ---
Vector(2,4)
class Vector:
"""
Class for 2-dimensional vectors
Supports standard vector operations, including scalar multiplication and vector addition.
"""
def __init__(self, x, y):
self.x = x
self.y = y
def scalar_multiply(self, c):
"""
Return a Vector with components multiplied by c
"""
return(Vector(c*self.x, c*self.y))
def __str__(self):
return("Vector(" + str(self.x) + "," + str(self.y) + ")")
def __add__(self, other):
return(Vector(self.x + other.x, self.y + other.y))
def __sub__(self, other):
return(Vector(self.x - other.x, self.y - other.y))
We can also add useful binary operations, like addition. The "magic" in "magic method" refers to the fact that Python will automatically use these methods when interpreting symbols like +
and *
. Often times, magic methods are extremely obvious to implement, and in this case it's ok not to document them.
There are MANY magic methods -- check out this blog post for a complete list. For now, let's just implement addition and subtraction.
u = Vector(1, 2)
v = Vector(1, 1)
print(u+v)
print(u-v)
# ---
Vector(2,3) Vector(0,1)