在 Python 中处理 unpickled 参数
使用Python中的多处理库,我们在场景后面pickle对象,让另一个处理它们应该保存的对象的背景。 有些对象(例如文件)是“不可腌制的”,需要特殊处理。 在下面的示例中,我使用 __getstate__
和 __setstate__
在我的类 Person
被 pickle 时进行操作。
class Person:
def __init__(self, name: str, age: float):
self.name = name
self.age = age
self.pow_func = lambda number: number * number
self.file = open(f'{name}_{age}_file', 'w')
def write_to_file(self, message: str):
self.file.write(message)
# When this isn't implemented, pickle try to serialize class.<locals> AKA __dict__
# If this function returns false, the function __setstate__ won't be called when unpickling
def __getstate__(self):
state = self.__dict__.copy()
temp = open('temp', 'wb')
for key, value in self.__dict__.items():
try:
pickle.dump(value, temp)
except Exception:
print(f'Cant pickle {key}, we need special treatment')
state.update({str(key) + '_pickle_change': str(value)})
del state[key]
return state
# This function responsible for the unpickling
def __setstate__(self, state: dict):
for key, value in state.items():
if '_pickle_change' not in key:
self.__dict__.update({key: value})
else:
print(f'Bad type: {key}, {value}')
# What should we do here?
pass
正如您所读到的,我将 _pickle_change 添加到每个 unpickle 对象的名称及其值的 str 中。 我的问题是,我应该在 __setstate__ 中做什么来调用文件和 lambda 函数,就像在 init 中所做的那样?我如何确保它是通用的?
Using the multiprocessing library in Python, we pickle objects behind the scene to let the other process a background of what objects they should hold.
Some objects like files are "unpickleable" and need special treatment.
In the following example, I used the __getstate__
and __setstate__
to operate when my class Person
is pickled.
class Person:
def __init__(self, name: str, age: float):
self.name = name
self.age = age
self.pow_func = lambda number: number * number
self.file = open(f'{name}_{age}_file', 'w')
def write_to_file(self, message: str):
self.file.write(message)
# When this isn't implemented, pickle try to serialize class.<locals> AKA __dict__
# If this function returns false, the function __setstate__ won't be called when unpickling
def __getstate__(self):
state = self.__dict__.copy()
temp = open('temp', 'wb')
for key, value in self.__dict__.items():
try:
pickle.dump(value, temp)
except Exception:
print(f'Cant pickle {key}, we need special treatment')
state.update({str(key) + '_pickle_change': str(value)})
del state[key]
return state
# This function responsible for the unpickling
def __setstate__(self, state: dict):
for key, value in state.items():
if '_pickle_change' not in key:
self.__dict__.update({key: value})
else:
print(f'Bad type: {key}, {value}')
# What should we do here?
pass
As you can read, I add _pickle_change to its name for every unpickle object and the str of its value.
My question is, What should I do in __setstate__
to recall the file and lambda functions as I did in init? How do I make sure it will be generic?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于上面的示例,您可以使用
ast
将文件打开器作为字符串获取,然后在 setstate 再次对其进行评估。对于 lambda 表达式,我们可以做很多事情。您可以使用lambdaser或dill。更通用的方法是注册您自己的pickler。更简单的方法是使用 pathos mp,它在引擎盖下使用 dill。
For the above example you could use
ast
to grab the file opener as string and later at setstate eval it back again. For lambdas there are plenty of thing one could to. You may use lambdser or dill. A in more generic way would be to register you own pickler.A more simpler approach would be to use pathos mp which uses dill under the hood.