Python 动态特性不能经受酸洗 特性\u pickle\u问题.py
上面的代码报告了一个动态特性。在这段代码中,一切都按预期工作。但是,使用新的python进程并执行以下操作:Python 动态特性不能经受酸洗 特性\u pickle\u问题.py,python,traits,pickle,Python,Traits,Pickle,上面的代码报告了一个动态特性。在这段代码中,一切都按预期工作。但是,使用新的python进程并执行以下操作: >>> from traits_pickle_problem import Person, Client >>> p=cPickle.load(open('testTraits.pkl','rb'))
>>> 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]
使它再次工作
在取消勾选过程中,我是否丢失了某些内容,或者是否需要在\uuuu setstate\uuuu
中重新建立处理程序
谢谢你的帮助。这适用于traits版本为4.30的windows上的Python 2.7(32位)。运行
pickletools.dis(cPickle.dumps(p))
,您可以看到正在引用的处理程序对象:
...
213: c GLOBAL 'traits.trait_handlers TraitListObject'
...
但是没有关于如何将它连接到报告
方法的更多信息。因此,要么trait_处理程序本身没有正确地进行pickle处理,要么它是一个短暂的东西,比如一个文件句柄,不能在第一时间进行pickle处理
在这两种情况下,最好的选择是重载\uuu setstate\uuu
,并在重新创建对象时重新连接事件处理程序。这并不理想,但至少所有内容都包含在对象中
class Person(object):
def __init__(self):
self.client = Client()
# dynamic handler
self.client.on_trait_event(self.report, 'data_items')
def __setstate__(self, d):
self.client = d['client']
self.client.on_trait_event(self.report, 'data_items')
def report(self, obj, name, old, new):
print 'client added-- ', new.added
现在取消勾选文件将正确注册事件处理程序:
p=cPickle.load(open('testTraits.pkl','rb'))
p.client.data.append(1000)
>>> client added-- [1000]
你可能会觉得有趣。它进入了如何在引擎盖下酸洗工作的高点
编辑-在改变特征时使用的初始响应
-一种似乎有效的打字错误。为清晰起见,将其更改回\u trait\u event上的。我也遇到了同样的问题,但结果是这样的:映像我只想pickle一个安静的大类的一部分,并且一些对象被设置为transient=True,因此它们不会被pickle,因为没有什么重要的东西需要保存,例如
class LineSpectrum(HasTraits):
andor_cam = Instance(ANDORiKonM, transient=True)
与应保存的对象不同,例如
spectrometer = Instance(SomeNiceSpectrometer)
在我的线谱课上,我有一个
def __init__(self, f):
super(LineSpectrum, self).__init__()
self.load_spectrum(f)
def __setstate__(self, state): # WORKING!
print("LineSpectrum: __setstate__ with super(...) call")
self.__dict__.update(state)
super(LineSpectrum, self).__init__() # this has to be done, otherwise pickled sliders won't work, also first update __dict__!
self.from_pickle = True # is not needed by traits, need it for myself
self.andor_cam = ANDORiKonM(self.filename)
self.load_spectrum(self.filename)
在我的例子中,这是完美的-所有滑块都在工作,对象被pickle时设置的所有值都被设置回原处
希望这对你或任何有同样问题的人有效。获得了Anaconda Python 2.7.11,更新了所有包
PS:我知道线程很旧,但不想为此打开一个新线程。我查看了hastraits资源,没有找到任何关于它如何存储回调处理程序的有用信息。我太不耐烦了。无论如何,问题似乎不在于代码,而在于特性。我觉得这有点老套,但我认为setstate是个不错的选择。请记住,setstate将实例dict作为参数接收,在重新建立处理程序之前,必须将其分配给self。
def __init__(self, f):
super(LineSpectrum, self).__init__()
self.load_spectrum(f)
def __setstate__(self, state): # WORKING!
print("LineSpectrum: __setstate__ with super(...) call")
self.__dict__.update(state)
super(LineSpectrum, self).__init__() # this has to be done, otherwise pickled sliders won't work, also first update __dict__!
self.from_pickle = True # is not needed by traits, need it for myself
self.andor_cam = ANDORiKonM(self.filename)
self.load_spectrum(self.filename)