2

我有一个类 ( 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__inBar以保存self._value&的解决方案self._more,但我也必须实例化该self._callback方法(即__init__()从外部类调用Foo传递回调函数.

但我无法弄清楚如何实现这一目标。

任何帮助深表感谢。
谢谢。

4

1 回答 1

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)或只需在您的代码中定义一个查找表。

假设您在查找表中定义了一小组可能的回调,只是一个快速(未经测试,抱歉!)示例:

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__你并没有真正为自己节省很多精力或头痛,因为它专门为你的应用程序构建了自己的方案。

于 2012-08-06T15:46:42.563 回答