butterwagon
butterwagon

Reputation: 499

Traitlets List won't run callback if the list is modified in-place

I have a class with a list trait that I'd like to use to call a function any time the list is modified.

class MyClass(traitlets.HasTraits):
    MyTrait = traitlets.List([0]*8, minlen=8, maxlen=8)


Foo = MyClass()


def Bar(change):
    print(change['new'])


Foo.observe(Bar, names='MyTrait')

The problem I have is that if I do something like the following, Bar doesn't get called:

Foo.MyTrait[0] = 5

If I want Bar to get called, I have to do something like this:

MyTraitCopy = Foo.MyTrait.copy()
MyTraitCopy[0] = 5
Foo.MyTrait = MyTraitCopy

This doesn't seem like the right way to do this. Is there a better way to register a callback to a change in a member of a List trait?

Upvotes: 2

Views: 629

Answers (1)

Louis
Louis

Reputation: 112

I've been playing with the widgets a lot recently, and traitlets does not seem to be able to observe such changes, there is the same problem with dictionnaries (see https://github.com/ipython/traitlets/issues/496 for more details).

In my project I had to detect the change of a dictionnary values with few keys. I added a counter key to the dictionnary and I recreated the dict each time it was updated... But copying seems to be the only way for now.

Upvotes: 2

Related Questions