我不得不说我确实没有问题,因为“一切正常”,但我很难理解为什么。
我正在python / urwid中编写脚本。在我的脚本中,我有一个ItemWidget类,其self._w等于3个小部件的urwid.Pile,每个小部件都是urwid.Text行。此外,类ItemWidget有一个属性self.visibility,它是一个包含三个布尔值的列表,另一个是self.rebuild()方法。 init函数是
def __init__ (self, content,vis):
self.content = content
self.visibility = vis
self.rebuild()
self.__super.__init__(self._w)
方法rebuild()根据self.visibility()中的值重建self._w。
在脚本的main()函数中,我有一个变量
globalvisibility = [1,1,1]
我创建了一个(大约1000个)ItemWidget实例的列表:
for content in abstracts: # (*)
items.append(ItemWidget(content,globalvisibility)) #
实际上我使用的是变量而不是
for content in abstracts.items():
items.append(ItemWidget(content,[1,1,1]))
只是因为稍后我将实现将全局可见性保存到文件中。但我认为除了初始化之外,它对任何事情都没有用。
无论如何,在脚本中我经常使用ItemWidget的实例并通过例如
更改其可见性item.visibility[2] = 0 # (**)
和类似的。到目前为止,一切正常并且符合预期。
这是我的问题。为什么在通过(*)创建ItemWidget的实例后,将变量globalvisibility更改为[0,1,1]会影响所有这些实例?
我不得不说我意外地“发现”它似乎非常有用(我认为要改变ItemWidget的所有实例的可见性原则,我将不得不遍历所有这些实例),但是 - 对我来说 - 非常奇怪。特别是考虑到操作(**)只影响单个实例。
我非常感谢一些解释。
编辑:整个脚本在这里: https://www.dropbox.com/s/a0a4a0asyi5lyxw/tescik.py?dl=0 和示例数据库,如果itemwidget是,我将从中创建实例: https://www.dropbox.com/s/zuwbvggznst85ru/arxiv-2013-05-23.db?dl=0
要运行它,您需要修改第58行以指向数据库。要查看行为,请滚动到某些项目并按Enter键 - 摘要将仅在这些项目上消失,然后按“显示摘要” - 这将重置所有项目的行为。
答案 0 :(得分:2)
为什么在通过(*)创建ItemWidget实例后,将变量globalvisibility更改为[0,1,1]会影响所有这些实例?
因为您在创建所有这些实例时都通过了globalvisibility
。所有实例都在vis
属性中存储对同一列表的引用。
如果您想避免这种情况,请在__init__
方法或创建实例时复制列表:
def __init__ (self, content,vis):
self.content = content
self.visibility = vis[:] # here
# etc.
或者:
for content in abstracts:
items.append(ItemWidget(content, globalvisibility[:]))
你在这里做出的确切选择取决于你是否会想要当前的行为。如果是这样,请将其从__init__()
中删除,并在制作实例时进行复制。