Reputation: 55
So I have a point class and a line class that both have a scale method.
class Point:
def __init__(self, x, y):
if not isinstance(x, float):
raise Error("Parameter \"x\" illegal.")
self.x = x
if not isinstance(y, float):
raise Error ("Parameter \"y\" illegal.")
self.y = y
def scale(self, f):
if not isinstance(f, float):
raise Error("Parameter \"f\" illegal.")
self.x = f * self.x
self.y = f * self.y
def __str__(self):
return '%d %d' % (int(round(self.x)), int(round(self.y)))
class Line:
def __init__(self, point0, point1):
self.point0 = point0
self.point1 = point1
def scale(self, factor):
if not isinstance(factor, float):
raise Error("Parameter \"factor\" illegal.")
self.point0.scale(factor)
self.point1.scale(factor)
def __str__(self):
return "%s %s" % (self.point0, self.point1)
So one of the tests I do on this code is to check for a shallow copy which I do in this test code.
p0.scale(2.0)
p1.scale(2.0)
print line
The problem is the print line gives me 0 2 4 6 and it should give me 0 1 2 3. So why is it printing multiples of 2 instead? The scale method is supposed to return the scaled values and for all the other test cases it prints the expected values however just with this test code it prints values I didn't expect. Here's how the values of p0 and p1 are set up:
print '********** Line'
print '*** constructor'
p0 = Point(0.0, 1.0)
p1 = Point(2.0, 3.0)
line = Line(p0,p1)
print line
Upvotes: 1
Views: 153
Reputation: 9010
In your __init__
method for Line
, you are assigning the names self.point0
and self.point1
to the two points that are passed in. This does not make a new copy, only gives the objects in memory another name. If you change this method to
def __init__(self, point0, point1):
self.point0 = Point(point0.x, point0.y)
self.point1 = Point(point1.x, point1.y)
then everything should work as intended. Or, you can use the copy module:
from copy import copy
class Line:
def __init__(self, point0, point1):
self.point0 = copy(point0)
self.point1 = copy(point1)
You could also define your own __copy__
and __deepcopy__
methods on your Point
class.
def __copy__(self):
return type(self)(self.x, self.y)
def __deepcopy__(self, memo):
return type(self)(self.x, self.y)
You can look at this question for more information.
Upvotes: 2
Reputation: 22041
Printing line
after scaling p0,p1
by 2 multiply x,y
pairs for p0, p1
. Line instance values of point0
and point1
pointing to instances of Point
which is p0 and p1 appropriately, as result of print line
you can see updated value of x,y
of each point.
p0 = Point(0,1)
p1 = Point(2,3)
line = Line(p0, p1)
print line # 0 1 2 3
p0.scale(2.0)
p1.scale(2.0)
print line # 0 2 4 6
Upvotes: 0