为什么 .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.children
(a += b
等同于 a = a.__iadd__(b)
如果 __iadd__
方法存在)。
每个 this 问题,原来这是一个 traitlets
问题。除非定义新列表,否则修改 self.children
的元素不会触发事件通知。
我有一个对象 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.children
(a += b
等同于 a = a.__iadd__(b)
如果 __iadd__
方法存在)。
每个 this 问题,原来这是一个 traitlets
问题。除非定义新列表,否则修改 self.children
的元素不会触发事件通知。