当 JSON 尝试使用 dict 中编码的类信息解码我的序列化自定义类时,我遇到了问题。我会尽量提供尽可能多的信息,所以请多多包涵。
我正在使用此处提供的优秀教程作为参考。我指的是详细说明为您自己的类编写编码/解码的部分。
我的包模块结构部分如下:
+--- PyDev Project
+-- src
+-- astar
| +-- __init__.py
| +-- astar.py
+-- common
| +-- __init__.py
| +-- service.py
| +-- graph.py
| +-- vertex.py
这些模块中的每一个都有自己的类。我在common.service模块中序列化Service类的对象。这基本上是通过 Pyro 连接使用的。
序列化代码为:
def convert_to_builtin_type(obj):
print('default(', repr(obj), ')')
# Convert objects to a dictionary of their representation
d = { '__class__':obj.__class__.__name__,
'__module__':obj.__module__,
}
d.update(obj.__dict__)
return d
反序列化代码为:
def dict_to_object(self, d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
# module = __import__(module_name)
module = import_module(module_name)
print('MODULE:', module)
class_ = getattr(module, class_name)
print('CLASS:', class_)
args = dict( (key.encode('ascii'), value) for key, value in d.items())
print('INSTANCE ARGS:', args)
inst = class_(**args)
else:
inst = d
return inst
该问题在反序列化期间发生。局部变量值是:
class_ = <module 'common.Service' from path-to-file.py>
class_name = 'Service'
module = <module 'common' from path-to-__init__.py>
module_name = 'common.Service'
失败的原因是因为class _ 返回的是 package.module 值,而不是该模块内的类名。从技术上讲,类_ 应该包含 common.service.Service,这是实际的类。因此,最后一条语句inst = class (**args)_ 因“TypeError: module object not callable”错误而失败。
我知道import或 importlib.import_module 都导入了那个顶级模块,但就我而言,我如何进入二级模块中的一个类?从技术上讲,第二级是模块,第一级是包,所以我需要 pkg.module 中的一个我无法访问的类。
我希望这个问题是有道理的,并且有足够的研究表明。如果需要澄清,我有更多信息。
编辑:用户建议解决了问题。
def dict_to_object(self, d):
if '__class__' in d:
class_name = d.pop('__class__')
module_name = d.pop('__module__')
# module = __import__(module_name)
__import__(module_name)
module = sys.modules[module_name]
print('MODULE:', module)
class_ = getattr(module, class_name)
print('CLASS:', class_)
args = dict((key, value) for key, value in d.items())
print('INSTANCE ARGS:', args)
inst = class_(**args)
else:
inst = d
return inst