更改Array元素时在Python traits包中触发事件

时间:2013-09-02 22:09:20

标签: python arrays numpy traits traitsui

我正在使用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,然后更改了[]运算符,以便它显式触发正确类型的特征事件。但希望这是一种蠕虫,我不必打开。

1 个答案:

答案 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