类方法可以将另一个类中的变量更改为不可预见的副作用吗?

时间:2016-10-16 11:38:43

标签: python class variables methods

我在两节课时遇到了一些问题。这就是我在主循环中写的内容

print(player1.getPosSize())    
ball.setPos(windowWidth, [player1.getPosSize(), player2.getPosSize()],
    [player1.getSpeed(), player2.getSpeed()])    
print(player1.getPosSize())

以下是方法定义,如果它有帮助

(球类)

def setPos(self, windowWidth, playerPosSizes, playerSpeed):       
    playerPosSizes[0].append(playerSpeed[0])
    playerPosSizes[1].append(playerSpeed[1])
    playerPosSizeSp = playerPosSizes

(玩家类)

def getPosSize(self):
    return self.posSize

def getSpeed(self):
    return self.ysp

这是输出:

[80, 285.0, 40, 150]    
[80, 285.0, 40, 150, 0.0]

因此getPosSize()返回的列表已更改。这很奇怪,因为getPosSize返回仅存在于类播放器中的列表posSize。我在AN OTHER类的方法中使用posSize的VALUE。我不知道如何更改posSize列表!我的意思是,当我致电getPosSize时,我会得到posSize的副本,对吧?因此,当我在球类的方法setPos中使用该副本时,原始posSize不应该更改。

如果代码看起来令人困惑,我真的很抱歉我试图只包含相关部分。

2 个答案:

答案 0 :(得分:0)

mutable之类的任何list对象都可以被任何有权访问它的对象更改。 IE浏览器。如果您的getPosSize()方法正在返回list本身,则可以进行更改,从而影响相同的列表。

class One(object):
    CLS_LST = [1, 2, 3]
    def __init__(self):
        self.lst = [4, 5, 6]

    def get_cls_pos(self):
        return One.CLS_LST

    def get_pos(self):
        return self.lst

class Two:
    def do_smthng(self, data):
        data.append(-1)



a = One()

print('This is One.CLS_LST: {}'.format(a.CLS_LST))
print('This is a.lst: {}'.format(a.lst))
b = Two()
print('Calling b do something with One.CLS_LST')
b.do_smthng(a.get_cls_pos())
print('This is One.CLS_LST: {}'.format(a.CLS_LST))
print('Calling b to do something with a.lst')
b.do_smthng(a.get_pos())
print('This is a.lst: {}'.format(a.lst))

此代码的结果将打印出来:

This is One.CLS_LST: [1, 2, 3]
This is a.lst: [4, 5, 6]
Calling b to do something with One.CLS_LST
This is One.CLS_LST: [1, 2, 3, -1]
Calling b to do something with a.lst
This is a.lst: [4, 5, 6, -1]

如果您确实要传递列表副本,请尝试使用return list[:]

答案 1 :(得分:0)

您的代码中的两个变量似乎链接到同一个列表,因此更改其中一个将改变另一个。

你没有像ball.posSize = player1.posSize那样做什么吗?

如果是,您创建了对同一列表的第二个引用。

要解决此问题,请将ball.posSize = player1.posSize更改为ball.posSize = player1.posSize[:]