【问题标题】:Python OOP, cannot overwrite instancesPython OOP,无法覆盖实例
【发布时间】:2018-01-07 02:32:22
【问题描述】:

我想创建 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>']

可以看出,第二个实例应该覆盖前一个实例,而是添加它。问题出在代码中吗?以及如何解决?

【问题讨论】:

  • 请创建一个minimal reproducible example。 “不覆盖”非常模糊。为什么你认为旧对象没有被覆盖?
  • 我不确定你为什么删除了这些调用,但现在这个问题没有任何意义。你应该创建一个代码的最小示例,而不是删除整个代码。
  • 我删除了代码,因为它是分配的,我不确定我是否可以把它放在这里,它也破坏了分配的目的。但是是的,我会以更好的方式更新它

标签: python-3.x oop instances


【解决方案1】:

好的, 您的tents_list 属性是一个类属性,因此即使您的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】:

对象被覆盖,但您将tents_list 定义为类变量,因此MITCampus 的所有实例共享此列表。 因此,任何新实例都会添加到该列表中,并且在您看来这没有被“覆盖”。

如果您想要这种“覆盖”行为,请将tents_list 移动到__init__ 方法中作为self.tents_list。只有这样它对于每个实例都是唯一的。

【讨论】:

    猜你喜欢
    • 2012-07-19
    • 2013-06-07
    • 2021-12-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    相关资源
    最近更新 更多