当变量在列表中时如何更改 class 的实例变量
How to change an instance variable of a class when that variable is inside a list
我正在 Python 中编写一个井字游戏,一方面我在 class 中有很多实例变量,它们都在一个列表中。我正在尝试更改一个实例变量,但是当它在列表中时,我只能更改列表元素。
这里是一些代码:
# 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']
有没有办法得到我预期的结果?
字符串是不可变对象,因此当您更改列表中具有给定索引的项目时,列表现在指向完全独立的字符串 X
.
同样的情况适用于此;
>>> configs[2] += "X"
>>> print configs[2]
'3X'
>>> print board.three
'3'
另一种方法是在列表中的项目更新时执行回调函数。 (但是,我个人不赞成这样做,因为这似乎是一个 hacky 解决方案。)
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'
您是否考虑过使用更好的数据结构?像字典,即
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 事实证明(检查后)您的 class 属性无论如何都会存储在 object.__dict__
中。所以为什么不使用你自己的。
还要澄清一下,可以通过定义 __getitem__
和 __setitem__
方法来使用您自己的 class 模拟容器对象,如下所示:
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
并且可以假装你的 class 是容器(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'}
我正在 Python 中编写一个井字游戏,一方面我在 class 中有很多实例变量,它们都在一个列表中。我正在尝试更改一个实例变量,但是当它在列表中时,我只能更改列表元素。
这里是一些代码:
# 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']
有没有办法得到我预期的结果?
字符串是不可变对象,因此当您更改列表中具有给定索引的项目时,列表现在指向完全独立的字符串 X
.
同样的情况适用于此;
>>> configs[2] += "X"
>>> print configs[2]
'3X'
>>> print board.three
'3'
另一种方法是在列表中的项目更新时执行回调函数。 (但是,我个人不赞成这样做,因为这似乎是一个 hacky 解决方案。)
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'
您是否考虑过使用更好的数据结构?像字典,即
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 事实证明(检查后)您的 class 属性无论如何都会存储在 object.__dict__
中。所以为什么不使用你自己的。
还要澄清一下,可以通过定义 __getitem__
和 __setitem__
方法来使用您自己的 class 模拟容器对象,如下所示:
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
并且可以假装你的 class 是容器(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'}