Python OOP,无法覆盖实例
Python OOP, cannot overwrite instances
我想制作 2 个具有相同名称的实例,例如
a = SomeClass(someAttr1)
a = SomeClass(someAttr2)
这样新的应该覆盖前一个。
我也试过这个:
a = SomeClass(someAttr1)
a = None
a = SomeClass(someAttr2)
我试过了,但它没有覆盖之前的实例,而是自己添加了它,有什么办法吗?
代码如下:
### Do not change the Location or Campus classes. ###
### Location class is the same as in lecture. ###
class Location(object):
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, deltaX, deltaY):
return Location(self.x + deltaX, self.y + deltaY)
def getX(self):
return self.x
def getY(self):
return self.y
def dist_from(self, other):
xDist = self.x - other.x
yDist = self.y - other.y
return (xDist ** 2 + yDist ** 2) ** 0.5
def __eq__(self, other):
return (self.x == other.x and self.y == other.y)
def __str__(self):
return '<' + str(self.x) + ',' + str(self.y) + '>'
class Campus(object):
def __init__(self, center_loc):
self.center_loc = center_loc
def __str__(self):
return str(self.center_loc)
class MITCampus(Campus):
""" A MITCampus is a Campus that contains tents """
tents_list = []
def __init__(self, center_loc, tent_loc=Location(0, 0)):
""" Assumes center_loc and tent_loc are Location objects
Initializes a new Campus centered at location center_loc
with a tent at location tent_loc """
# Your code here
Campus.__init__(self, center_loc)
self.tent_loc = tent_loc
self.tents_list.append(self.tent_loc)
def add_tent(self, new_tent_loc):
""" Assumes new_tent_loc is a Location
Adds new_tent_loc to the campus only if the tent is at least 0.5 distance
away from all other tents already there. Campus is unchanged otherwise.
Returns True if it could add the tent, False otherwise. """
# Your code here
new_tent_flag = True
for loc in self.tents_list:
if loc == new_tent_loc or new_tent_loc.dist_from(loc) < 0.5:
new_tent_flag = False
if new_tent_flag:
self.tents_list.append(new_tent_loc)
return True
else:
return False
def get_tents(self):
""" Returns a list of all tents on the campus. The list should contain
the string representation of the Location of a tent. The list should
be sorted by the x coordinate of the location. """
# Your code here
new_list_sorted = sorted(self.tents_list, key=lambda tent: tent.getX())
str_list = []
for x in new_list_sorted:
str_list.append(x.__str__())
return str_list
测试用例:
Test: 0
c = MITCampus(Location(1,2))
print(c.add_tent(Location(1,2)))
print(c.add_tent(Location(0,0)))
print(c.add_tent(Location(2,3)))
print(c.add_tent(Location(2,3)))
print(c.get_tents())
Output:
True
False
True
False
['<0,0>', '<1,2>', '<2,3>']
Test: 1
init campus with default tent loc
c = MITCampus(Location(-1,-2))
print(sorted(c.get_tents()))
Output:
['<0,0>','<0,0>', '<1,2>', '<2,3>']
Expected Output:
['<0,0>']
可以看出,第二个实例应该覆盖前一个实例,但它正在添加它。问题出在代码中吗?以及如何解决?
对象被覆盖,但您将 tents_list
定义为 class 变量,因此 MITCampus
的所有实例共享 此列表。
因此,任何新实例都会添加到该列表中,在您看来这不是 "overwritten".
如果您想要 "overwriting" 行为,请将 tents_list
作为 self.tents_list
移动到 __init__
方法中。只有这样,它对于每个实例都是唯一的。
好的,
您的 tents_list
属性是一个 class 属性,因此即使您的 c
对象被覆盖,tents_list
属性也保持不变。
最好让你的 tents_list 成为对象参数,这样 tents_list
属性也会被覆盖。
def __init__(self, center_loc, tent_loc=Location(0, 0)):
Campus.__init__(self, center_loc)
self.tents_list = [] # <--- Add this
self.tent_loc = tent_loc
self.tents_list.append(self.tent_loc)
我想制作 2 个具有相同名称的实例,例如
a = SomeClass(someAttr1)
a = SomeClass(someAttr2)
这样新的应该覆盖前一个。
我也试过这个:
a = SomeClass(someAttr1)
a = None
a = SomeClass(someAttr2)
我试过了,但它没有覆盖之前的实例,而是自己添加了它,有什么办法吗?
代码如下:
### Do not change the Location or Campus classes. ###
### Location class is the same as in lecture. ###
class Location(object):
def __init__(self, x, y):
self.x = x
self.y = y
def move(self, deltaX, deltaY):
return Location(self.x + deltaX, self.y + deltaY)
def getX(self):
return self.x
def getY(self):
return self.y
def dist_from(self, other):
xDist = self.x - other.x
yDist = self.y - other.y
return (xDist ** 2 + yDist ** 2) ** 0.5
def __eq__(self, other):
return (self.x == other.x and self.y == other.y)
def __str__(self):
return '<' + str(self.x) + ',' + str(self.y) + '>'
class Campus(object):
def __init__(self, center_loc):
self.center_loc = center_loc
def __str__(self):
return str(self.center_loc)
class MITCampus(Campus):
""" A MITCampus is a Campus that contains tents """
tents_list = []
def __init__(self, center_loc, tent_loc=Location(0, 0)):
""" Assumes center_loc and tent_loc are Location objects
Initializes a new Campus centered at location center_loc
with a tent at location tent_loc """
# Your code here
Campus.__init__(self, center_loc)
self.tent_loc = tent_loc
self.tents_list.append(self.tent_loc)
def add_tent(self, new_tent_loc):
""" Assumes new_tent_loc is a Location
Adds new_tent_loc to the campus only if the tent is at least 0.5 distance
away from all other tents already there. Campus is unchanged otherwise.
Returns True if it could add the tent, False otherwise. """
# Your code here
new_tent_flag = True
for loc in self.tents_list:
if loc == new_tent_loc or new_tent_loc.dist_from(loc) < 0.5:
new_tent_flag = False
if new_tent_flag:
self.tents_list.append(new_tent_loc)
return True
else:
return False
def get_tents(self):
""" Returns a list of all tents on the campus. The list should contain
the string representation of the Location of a tent. The list should
be sorted by the x coordinate of the location. """
# Your code here
new_list_sorted = sorted(self.tents_list, key=lambda tent: tent.getX())
str_list = []
for x in new_list_sorted:
str_list.append(x.__str__())
return str_list
测试用例:
Test: 0
c = MITCampus(Location(1,2))
print(c.add_tent(Location(1,2)))
print(c.add_tent(Location(0,0)))
print(c.add_tent(Location(2,3)))
print(c.add_tent(Location(2,3)))
print(c.get_tents())
Output:
True
False
True
False
['<0,0>', '<1,2>', '<2,3>']
Test: 1
init campus with default tent loc
c = MITCampus(Location(-1,-2))
print(sorted(c.get_tents()))
Output:
['<0,0>','<0,0>', '<1,2>', '<2,3>']
Expected Output:
['<0,0>']
可以看出,第二个实例应该覆盖前一个实例,但它正在添加它。问题出在代码中吗?以及如何解决?
对象被覆盖,但您将 tents_list
定义为 class 变量,因此 MITCampus
的所有实例共享 此列表。
因此,任何新实例都会添加到该列表中,在您看来这不是 "overwritten".
如果您想要 "overwriting" 行为,请将 tents_list
作为 self.tents_list
移动到 __init__
方法中。只有这样,它对于每个实例都是唯一的。
好的,
您的 tents_list
属性是一个 class 属性,因此即使您的 c
对象被覆盖,tents_list
属性也保持不变。
最好让你的 tents_list 成为对象参数,这样 tents_list
属性也会被覆盖。
def __init__(self, center_loc, tent_loc=Location(0, 0)):
Campus.__init__(self, center_loc)
self.tents_list = [] # <--- Add this
self.tent_loc = tent_loc
self.tents_list.append(self.tent_loc)