我正在使用Python的traits包,我正在尝试找出使用traits.trait_numeric.Array类的正确方法。使用数组特征编写traits.api.HasTraits的子类是很简单的,这样当数组发生更改时,会触发on_trait_change,但我无法弄清楚当数组元素被修改时如何触发任何类型的事件到位。这是一个最小的例子:
from traits.api import HasTraits
from traits.trait_numeric import Array
import numpy as np
class C(HasTraits):
x = Array
def __init__(self):
self.on_trait_event(self.do_something, 'x')
def do_something(self):
print 'Doing something'
c = C()
# This line calls do_something()
c.x = np.linspace(0,1,10)
# This one doesn't, and I wish it did
c.x[3] = 100
# Same with this one
c.x[:] = np.ones(c.x.shape)
我希望有一些内置的traits.trait_numeric.Array功能,我不知道,因为检测到数组的某个部分发生了变化似乎是一个非常标准的事情。
除此之外,我认为这个问题可以通过创建一个自定义特征类来解决,该类也继承了numpy.array,然后更改了[]运算符,以便它显式触发正确类型的特征事件。但希望这是一种蠕虫,我不必打开。
答案 0 :(得分:8)
我担心这不太可能。 numpy数组查看原始内存。任何东西都可以改变那个内存,而无需通过numpy数组对象本身。我们通常使用的模式是在执行切片/索引分配后重新分配整个数组。
import numpy as np
from traits.api import Array, HasTraits, NO_COMPARE
class C(HasTraits):
x = Array(comparison_mode=NO_COMPARE)
def _x_changed(self):
print 'Doing something'
c = C()
c.x = np.linspace(0, 1, 10)
# This does not trigger:
c.x[3] = 100
# This does:
c.x = c.x