当该变量在列表中时,如何更改类的实例变量

时间:2015-02-19 00:45:47

标签: python class

我正在用Python写一个tic-tac-toe游戏,一部分我在一个类中有很多实例变量,它们都在列表中。我试图更改一个实例变量,但当它在列表中时,我只能更改列表元素。

这里有一些代码:

# only a piece of my code

class Board(object):
    def __init__(self):
        self.one = "1"
        self.two = "2"
        self.three = "3"

board = Board()

configs = [board.one, board.two, board.three]
configs[2] = "X"
print board.three
print configs

预期结果:

X
['1', '2', 'X']

实际结果:

3
['1', '2', 'X']

有没有办法获得我预期的结果?

2 个答案:

答案 0 :(得分:1)

字符串是不可变对象,因此当您使用给定索引更改列表中的项目时,列表现在指向完全独立的字符串X

同样的情况适用于此;

>>> configs[2] += "X"
>>> print configs[2]
'3X'

>>> print board.three
'3'

一种替代方法是在列表中的项目更新时执行回调函数。 (但是,我个人不鼓励这样做,因为这似乎是一个黑客的解决方案。)

class interactive_list(list):
    def __init__(self, *args, **kwargs):
        self.callback = kwargs.pop('callback', None)
        super(interactive_list, self).__init__(*args, **kwargs)

    def __setitem__(self, index, value):
        super(interactive_list, self).__setitem__(index, value)
        if self.callback:
            self.callback(index, value)

>>> board = Board()

>>> def my_callback(index, value):
...    if index == 2:
...        board.three = value

>>> configs = interactive_list([board.one, board.two, board.three], callback=my_callback)
>>> configs[2] = 'X'

>>> print board.three
'X'

答案 1 :(得分:1)

您是否考虑过使用更好的数据结构?像字典一样,

class Board(object):
    def __init__(self):
        self.dict = {"one":"1", "two":"2", "three":"3"}

然后你可以做类似的事情:

>>> a = Board()
>>> a.dict
{'three': '3', 'two': '2', 'one': '1'}
>>> for element in a.dict:
    a.dict[element] = element+"x"
>>> a.dict
{'three': 'threex', 'two': 'twox', 'one': 'onex'}
>>> a.dict["one"] = "1"
>>> a.dict
{'three': 'threex', 'two': 'twox', 'one': '1'}

您正在寻找的解决方案也是可能的(最有可能是一些非常奇怪的getattrs等等......我不会真的推荐它。

Edit1 事实证明(检查后)您的类属性无论如何都将存储在object.__dict__中。那为什么不使用你自己的。

也是为了澄清它可以通过定义__getitem____setitem__方法来模拟容器对象,如下所示:

class Board(object):
    def __init__(self):
        self.dict = {"one":"1", "two":"2", "three":"3"}
    def __getitem__(self,key):
        return self.dict[key]
    def __setitem__(self, key, value):
        self.dict[key] = value

这意味着你不必在任何地方继续写a.dict,并且可以假装你的班级是像下面这样的容器(dict):

>>> a = Board()
>>> a.dict
{'three': '3', 'two': '2', 'one': '1'}
>>> a["one"]
'1'
>>> a["one"] = "x"
>>> a.dict
{'three': '3', 'two': '2', 'one': 'x'}