构造函数将覆盖已创建对象的先前值

时间:2014-04-02 19:46:02

标签: python oop

我对Python比较陌生。我正在一个项目中创建对象Square和Points。 Square由4个点组成,即左上角,右上角等。

现在在我的main函数中我创建了4个点对象并将它们发送给Square类的构造函数,它创建了我的Square。

当我对另一个具有不同点对象值的Square执行相同操作时,我先前创建的Square的值将被覆盖,因此最后我有两个相同的对象。你知道为什么会这样吗?

这是我的代码:

class Point(object):
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y

class Square(object):
    ul = Point()
    ll = Point()
    ur = Point()
    lr = Point()
    def __init__(self, ul, ll, ur, lr):
        self.ul.x = ul.x
        self.ll.x = ll.x
        self.ur.x = ur.x
        self.lr.x = lr.x
        self.ul.y = ul.y
        self.ll.y = ll.y
        self.ur.y = ur.y
        self.lr.y = lr.y

def main():
    ul1 = Point(1, 2)
    ll1 = Point(1, 1)
    ur1 = Point(2, 2)
    lr1 = Point(2, 1)
    s1 = Square(ul1, ll1, ur1, lr1)

    ul2 = Point(3, 3)
    ll2 = Point(3, 2)
    ur2 = Point(4, 3)
    lr2 = Point(4, 2)
    s2 = Square(ul2, ll2, ur2, lr2)

    #At this point s1 and s2 have the same values...

if __name__ == '__main__':
    main()

任何形式的帮助都将受到高度赞赏;)

干杯!

1 个答案:

答案 0 :(得分:5)

这种情况正在发生,因为您已将Square类中的四个角点变量定义为类变量。这意味着它们在该类的所有实例之间共享。

以下是Square课程的更简洁版本。有实例变量self.ul, self.ll等等。您不需要在Point中为这些实例指定__init__实例,因为您已经在主函数中执行此操作,并将它们作为参数传递。

class Square(object):
    def __init__(self, ul, ll, ur, lr):
        self.ul = ul
        self.ll = ll
        self.ur = ur
        self.lr = lr 

def main():
    s1 = Square(Point(1, 2), Point(1, 1), Point(2, 2), Point(2, 1))
    s2 = Square(Point(3, 3), Point(3, 2), Point(4, 3), Point(4, 2))
    print s1.ul.x # 1
    print s1.lr.y # 2

HyperBoreus提出了将点作为参数传递的好处,就好像您将相同的点对象传递给两个方块并对其进行修改一样,您所做的任何更改都将反映在两个方块中。

您可以通过将角落值传递给__init__而不是Point个对象来解决此问题,然后在__init __

中创建实例

这是一个完整的例子:

class Point(object):
    def __init__(self, x = 0, y = 0):
        self.x = x
        self.y = y

class Square(object):
    def __init__(self, ul, ll, ur, lr):
        self.ul = Point(ul[0], ul[1])
        self.ll = Point(ll[0], ll[1])
        self.ur = Point(ur[0], ur[1])
        self.lr = Point(lr[0], lr[1])

def main():
    square_one = Square((1, 2), (1, 1), (2, 2), (2, 1))
    square_two = Square((3, 3), (3, 2), (4, 3), (4, 2))

我还建议你使用更易读的变量名。您只需将upper_right缩短为ur即可节省任何费用。相反,当你在一年内回到这段代码时,你会诅咒自己。