自定义/动态类Pickle抛出“No module named xyz”错误的解决咨询
解决方案
方法一:修改生成类的__module__属性
直接在生成类后,将其__module__设置为__main__,同时调整自定义函数的模块归属,确保序列化时不依赖原模块:
修改generate_class_module.py中的函数:
def generate_class(custom_func): class MyClass: def __init__(self): self.custom_func = custom_func def do_something_custom(self, arg1): return self.custom_func(arg1) # 将生成的类归属到__main__模块 MyClass.__module__ = '__main__' # 同步调整自定义函数的模块归属,避免序列化后找不到函数定义 if hasattr(custom_func, '__module__'): custom_func.__module__ = '__main__' return MyClass
调用模块的代码无需修改,序列化后客户端反序列化时,会将类识别为__main__.MyClass,无需依赖generate_class_module。
方法二:使用type动态创建类
通过type函数直接在__main__模块下生成类,从根源上解决模块归属问题:
修改generate_class_module.py:
def generate_class(custom_func): # 定义类的方法 def __init__(self): self.custom_func = custom_func def do_something_custom(self, arg1): return self.custom_func(arg1) # 动态创建类,指定模块为__main__ MyClass = type( 'MyClass', # 类名 (object,), # 父类 { '__init__': __init__, 'do_something_custom': do_something_custom, '__module__': '__main__' # 明确模块归属 } ) # 调整自定义函数的模块归属 custom_func.__module__ = '__main__' return MyClass
这种方式生成的类天生归属__main__,序列化时dill会完整保存类的结构,客户端反序列化时无需额外依赖。
额外注意事项
- 若自定义函数
custom_func依赖其他模块的对象,需确保这些依赖也能被dill序列化,或同样调整其模块归属为__main__。 - 序列化时可开启dill的递归序列化选项,确保所有依赖都被保存:
import dill dill.settings['recurse'] = True
内容的提问来源于stack exchange,提问作者spacecheese
相关产品推荐
相关产品推荐

