我在编写自己的类来管理二维表时遇到了一个问题。
我开始创建一个简单的类,如下所示,创建一个empty_line对象,该对象被复制到创建行数所需的数量:
class Table(object):
"""Table class, allows the creation of new lines and columns to the table"""
def __init__(self, col = 1, lines = 1, defaultcontent=''):
self.columns = col
self.lines = lines
self.empty_line = [defaultcontent for i in range(self.columns)]
self.table = [self.empty_line for j in range(self.lines)]
def add_line(self):
self.table.append(self.empty_line)
self.lines += 1
def add_column(self):
self.empty_line.append('')
for i in range(self.lines):
self.table[i].append('')
然而,在我创建了一个表,例如用table = Table(5,3)
,并用table.table[1][2] = 'something'
进行赋值后,我意识到'something'
在每一行中都存在,如果不更改其他行,我就无法更改任何一行。self.empty_line
也发生了变化。
过了一会儿,我开始思考self.empty_line
使用中的问题。我重写了我的类,这次去掉了self.empty_line
,用基元['' for i in range(self.columns)]
替换它(当然,还纠正了add_column()
方法中添加两列而不是一列的错误!(。
我的问题消失了,但一个问题仍然存在:self.table = [self.empty_line for j in range(self.lines)]
不应该为每一行创建一个self.empty_line
对象的副本吗,而不是以某种方式"链接"相同的self.empty_line
实例(它被更改了(。
那么,我做错了什么,我对python对象的知识漏洞在哪里?
在您的代码中:
self.empty_line = [defaultcontent for i in range(self.columns)]
self.table = [self.empty_line for j in range(self.lines)]
empty_line使用燕子复制复制到表的每一行中。您只复制了引用,而不是默认内容。
解决方法:
self.table = [[default_content] * self.columns for _ in range(self.lines)]
add_line也有同样的问题。不要存储empty_line,而是使用default_content。
self.table.append([self.default_content] * self.columns)
...
请参阅:Python复制列表