python - 类变量的难以理解的行为

标签 python class

我不得不说我真的没有问题,因为“一切正常”,但我很难理解为什么。

我正在用 python/urwid 编写脚本。在我的脚本中,我有一个 ItemWidget 类,其 self._w 等于 3 个小部件的 urwid.Pile,每个小部件都是一行 urwid.Text。此外,类 ItemWidget 有一个属性 self.visibility,它是三个 bool 值的列表,还有一个方法 self.rebuild()。初始化函数是

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 键 - 摘要将仅在这些项目上消失,然后按“显示摘要” - 这将重置所有项目的行为。

最佳答案

Why after creating the instances of ItemWidget via (*), changing the variable globalvisibility to, say, [0,1,1] affects all these instances?

因为您在创建所有这些实例时传递了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__() 之外,并在创建实例时进行复制。

关于python - 类变量的难以理解的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28309279/

相关文章:

c++ - 如何存储和调用可变参数函数和值 vector ?

python - 如何在django中保存多个同名的html输入?

python - 检查目标 : expected softmax_1 to have shape (1, 时出错,但得到形状为 (2,)' 的数组,Keras

C++ const 函数错误

c# - 如何防止拆箱 - 读取任意 sql 行时装箱内存开销

c++ - 如何使我的类成员函数无法在 main 中调用?

python - 了解图像是否与用于训练卷积神经网络的数据集相关的有效方法

python - 尽管 update_idletasks() ,tkinter 光标直到操作后才发生变化

python - 正则表达式在 python 模拟器中有效,但在 perl 中无效

c++ - 错误 : cannot convert 'Vector (*)(double, Vector)' to 'ForwardEulerSolver*' in initialization