【发布时间】:2022-08-10 05:14:28
【问题描述】:
我的问题是,当我在序列化之前通过在__main__ 中“重新声明”它们来“强制”Python 类/函数定义与对象一起序列化时,未来会产生什么影响。
细节
如果定义不在__main__ 中,那么像pickle 和dill 这样的Python 库不会将类或函数定义与对象一起序列化,这是一个常见的问题。
因此,在反序列化对象时,必须在与序列化期间相同的位置找到其依赖项。这增加了部署的一些开销/不灵活性,因为定义必须维护在一个单独的包中,该包必须进行版本控制并存在于(生产)环境中。
我有时会在序列化它们之前使用“维护”对象的解决方法,例如 Oege Dijk here 所述。它本质上是在__main__ 中重新声明对象的定义,以便将其序列化。我使用的代码如下所示。
到目前为止,这种方法在我所有的(机器学习)工作流程中运行良好,已经有一段时间了。然而,它看起来很hacky,我想知道它是否会导致问题,以及哪个。当然,轻松修改序列化定义的能力已被删除(例如错误修复)。但这是我可以忍受的。还有其他我不知道的危险吗?
import inspect
import types
def mainify(obj):
if obj.__module__ != \'__main__\':
import __main__
is_func = True if isinstance(obj, types.FunctionType) else False
# Get source code and compile
source = inspect.getsource(obj if is_func else obj.__class__)
compiled = compile(source, \'<string>\', \'exec\')
# \"Declare\" in __main__ and keep track which key
# of __main__ dict is new
pre = list(__main__.__dict__.keys())
exec(compiled, __main__.__dict__)
post = list(__main__.__dict__.keys())
new_in_main = list(set(post) - set(pre))[0]
# for function return mainified version, else assign new
# class to obj and return object
if is_func:
obj = __main__.__dict__[new_in_main]
else:
obj.__class__ = __main__.__dict__[new_in_main]
return obj
标签: python serialization pickle dill