我有一个类(Bar
),它有效地拥有自己的状态和回调,并被另一个类(Foo
)使用:
class Foo(object):
def __init__(self):
self._bar = Bar(self.say, 10)
self._bar.work()
def say(self, msg):
print msg
class Bar(object):
def __init__(self, callback, value):
self._callback = callback
self._value = value
self._more = { 'foo' : 1, 'bar': 3, 'baz': 'fubar'}
def work(self):
# Do some work
self._more['foo'] = 5
self._value = 10
self._callback('FooBarBaz')
Foo()
显然我不能挑选课程Foo
因为Bar
有一个实例方法,所以我留下了以下实施__getstate__
&的解决方案。 __setstate__
Bar
self._value
保存self._more
& self._callback
,但我必须实例化__init__()
方法(即通过回调函数从外部类Foo
调用{{1}}。
但我无法弄清楚如何实现这一点。
非常感谢任何帮助 感谢。
答案 0 :(得分:1)
我认为如果您需要序列化这样的东西,您需要能够将回调定义为字符串。例如,您可能会说callback = 'myproject.callbacks.foo_callback'
。
基本上在__getstate__
中,您可以将_callback
函数替换为可用于稍后查找函数的内容,例如self._callback.__name__
。
在__setstate__
中,您可以使用函数替换_callback
。
这取决于你的所有函数都有真实名称所以你不能使用lambda作为回调并期望它被序列化。您还需要一个合理的机制来按名称查找您的功能。
您可以使用__import__
(类似于:'myproject.somemodule.somefunc'点名称语法可以支持这种方式,请参阅http://code.google.com/p/mock/source/browse/mock.py#1076)或只在代码中定义查找表。< / p>
快速(未经测试,抱歉!)示例假设您在查找表中定义了一小组可能的回调:
def a():
pass
callbacks_to_name = {a: 'a'
# ...
}
callbacks_by_name = {'a': a,
# ...
}
class C:
def __init__(self, cb):
self._callback = cb
def __getstate__(self):
self._callback = callbacks_to_name[self._callback]
return self.__dict__
def __setstate__(self, state):
state[_callback] = callbacks_by_name[self._callback]
我不确定您的用例是什么,但我建议您通过将工作项序列化为JSON或XML并编写一组简单的函数来自行序列化和反序列化。
好处是人类可以读取和理解序列化格式,并在升级软件时进行修改。 Pickle很有诱惑力,因为它似乎足够接近,但是当你有一堆__getstate__
和__setstate__
时,你还没有真正为自己的应用程序专门为自己的应用程序而努力或头疼