gpt4 book ai didi

python - (Un)Pickle 类具有 Instancemethod 对象

转载 作者:太空宇宙 更新时间:2023-11-04 06:21:29 24 4
gpt4 key购买 nike

我有一个类 (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()

显然我不能 pickle 类 Foo 因为 Bar 有一个实例方法,所以我剩下以下实现 __getstate__ 的解决方案> & __setstate__Bar 中保存 self._value & self._more,但我必须实例化 self._callback 方法(即从外部类 Foo 调用 __init__() 传递回调函数。

但我不知道如何实现这一目标。

非常感谢任何帮助。
谢谢。

最佳答案

我认为如果你需要序列化这样的东西,你需要能够将你的回调定义为一个字符串。例如,您可以说 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__ 时,你并没有真正为自己节省很多精力或头痛来构建你的专为您的应用而设计的方案。

关于python - (Un)Pickle 类具有 Instancemethod 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11831020/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com