【发布时间】:2014-04-12 16:37:07
【问题描述】:
traits_pickle_problem.py
from traits.api import HasTraits, List
import cPickle
class Client(HasTraits):
data = List
class Person(object):
def __init__(self):
self.client = Client()
# dynamic handler
self.client.on_trait_event(self.report,'data_items')
def report(self,obj,name,old,new):
print 'client added-- ' , new.added
if __name__ == '__main__':
p = Person()
p.client.data = [1,2,3]
p.client.data.append(10)
cPickle.dump(p,open('testTraits.pkl','wb'))
上面的代码报告了一个动态特征。这段代码中的一切都按预期工作。但是,使用 new python 进程并执行以下操作:
>>> from traits_pickle_problem import Person, Client
>>> p=cPickle.load(open('testTraits.pkl','rb'))
>>> p.client.data.append(1000)
导致列表追加无报告。但是,单独重新建立监听器如下:
>>> p.client.on_trait_event(p.report,'data_items')
>>> p.client.data.append(1000)
client added-- [1000]
让它再次工作。
我是否遗漏了什么,或者是否需要在 unpickling 过程中在 __setstate__ 中重新建立处理程序。
任何帮助表示赞赏。这适用于具有 4.30 特性的 Windows 上的 Python 2.7(32 位)。
【问题讨论】:
-
我查看了hastraits 源,找不到任何关于它如何存储回调处理程序的有用信息。我太不耐烦了。无论如何,问题似乎不在于您的代码,而在于特性。我觉得它很hacky,但我认为 setstate 是要走的路。请记住,setstate 接收实例 dict 作为参数,您必须在重新建立处理程序之前将其分配给 self.__dict__。