您无法获得“给定实例的类的完整路径”
class”,因为Python中没有这样的东西。对于
实例,以您的示例为基础:
>>> class B(object):
... class C(object):
... pass
...
>>> D = B.C
>>> x = D()
>>> isinstance(x, B.C)
True
“类路径”应该是什么x
be? D
or B.C
?两者都是
同样有效,因此 Python 没有给你任何告诉你的方法
来自另一个。
确实,即使是 Pythonpickle
模块在酸洗对象时遇到问题x
:
>>> import pickle
>>> t = open('/tmp/x.pickle', 'w+b')
>>> pickle.dump(x, t)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.6/pickle.py", line 1362, in dump
Pickler(file, protocol).dump(obj)
...
File "/usr/lib/python2.6/pickle.py", line 748, in save_global
(obj, module, name))
pickle.PicklingError: Can't pickle <class '__main__.C'>: it's not found as __main__.C
所以,总的来说,除了添加属性之外我没有其他选择
给你所有的班级(比如,_class_path
),你的序列化代码会查找它
将类名记录为序列化格式:
class A(object):
_class_path = 'mymodule.A'
class B(object):
_class_path = 'mymodule.A.B'
...
您甚至可以使用以下命令自动执行此操作一些元类魔法 https://stackoverflow.com/questions/639162/python-determine-if-a-class-is-nested/639588#639588(但也请阅读其他评论同一个帖子 https://stackoverflow.com/questions/639162/python-determine-if-a-class-is-nested/如果您执行以下操作,则可能适用的警告D=B.C
above).
也就是说,如果您可以将序列化代码限制为 (1) 个实例
的新式类,并且(2)这些类是在
模块的顶层,那么你可以复制什么pickle
做
(功能save_global
来自 Python 的 pickle.py 中的第 730--768 行
2.6)。
这个想法是每个新式类都定义属性__name__
and __module__
,它们是扩展为类名的字符串(如
在源中找到)和模块名称(如在sys.modules
);通过保存这些,您可以稍后导入模块并
获取该类的一个实例:
__import__(module_name)
class_obj = getattr(sys.modules[module_name], class_name)