为什么 .append() 在此列表上不起作用?

Why does .append() not work on this list?

我有一个对象 scene,它是 class Scene 的一个实例,并且有一个列表 children returns:

[<pythreejs.pythreejs.Mesh object at 0x000000002E836A90>, <pythreejs.pythreejs.SurfaceGrid object at 0x000000002DBF9F60>, <pythreejs.pythreejs.Mesh object at 0x000000002E8362E8>, <pythreejs.pythreejs.AmbientLight object at 0x000000002E8366D8>, <pythreejs.pythreejs.DirectionalLight object at 0x000000002E836630>]

如果我想用 point 更新此列表,其类型为:

<class 'pythreejs.pythreejs.Mesh'>

我需要执行:

scene.children = list(scene.children) + [point]

通常,我会执行:

scene.children.append(point)

然而,虽然这两种方法都附加 point,但只有第一种方法实际更新列表并产生预期的输出(即网格上的体素)。为什么?

可以找到完整的代码here

我猜你的问题是由于 children 是一个 property(或其他描述符)而不是你正在与之交互的 Scene 实例的简单属性。您可以获得子项列表,或将新的子项列表分配给属性,但您正在处理的列表并不是 class 在内部跟踪其子项的真正方式。如果您修改从 scene.children 获得的列表,则修改不会反映在 class.

测试此方法的一种方法是将 scene.children 中的列表多次保存在不同的变量中,看看它们是否都是同一个列表。尝试:

a = scene.children
b = scene.children
c = scene.children

print(id(a), id(b), id(c))

我怀疑每个列表的 id 会有所不同。

这里有一个 class 演示了您遇到的相同问题:

class Test(object):
    def __init__(self, values=()):
        self._values = list(values)

    @property
    def values(self):
        return list(self._values)

    @values.setter
    def values(self, new_values):
        self._values = list(new_values)

每次检查 values 属性,您都会得到一个新的(复制的)列表。

我认为没有与您发现有效的根本不同的修复。您可以使用以下方法稍微简化一些事情:

scene.children += [point]

由于 += 运算符在 Python 中的工作方式,这扩展了列表,然后将其重新分配回 scene.childrena += b 等同于 a = a.__iadd__(b) 如果 __iadd__ 方法存在)。

每个 this 问题,原来这是一个 traitlets 问题。除非定义新列表,否则修改 self.children 的元素不会触发事件通知。