我想序列化我的复杂对象。这看起来很简单,但每一步都会产生不同的问题。在
最后,其他程序员也必须能够创建继承自父对象的复杂对象。对于python2.7和Python3.x,这个对象应该是可pickle的
我从一个简单的对象开始,并成功地使用了pickle.dump
和{
然后我创建了多个复杂的对象(相似但不完全相同),其中一些可以转储,少数不能转储。在
pickle库knows,该库中的对象是否可以被pickle。理论上,这意味着^{
我想要一个独立于对象内容的可靠序列化。所以我搜索了其他序列化工具:
builtins.TypeError: <lib.scan.Content object at 0x7f37f1e5da50> is not JSON serializable
我读了How to check if an object is pickleable,但没有给我答复。在
我找到的最接近的是How to find source of error in Python Pickle on massive object
我将其调整为:
import pickle
if _future_.isPython3():
class MyPickler(pickle._Pickler):
def save(self, obj):
try:
pickle._Pickler.save(self, obj)
except:
print ('pick(3.x) {0} of type {1}'.format(obj, type(obj)))
else:
class MyPickler (pickle.Pickler):
def save(self, obj):
try:
pickle.Pickler.save(self, obj)
except:
print('pick(2.x)', obj, 'of type', type(obj))
我将此代码称为:
^{pr2}$我希望在引发异常之前执行保存。打印obj
的内容,这样我就可以准确地看到错误或错误所在。但结果是:
pick(3.x) <class 'module'> of type <class 'type'>
pick(3.x) <class 'module'> of type <class 'type'>
pick(3.x) <class 'Struct'> of type <class 'type'>
pick(3.x) <class 'site.setquit.<locals>.Quitter'> of type <class 'type'>
pick(3.x) <class 'site.setquit.<locals>.Quitter'> of type <class 'type'>
pick(3.x) <class 'module'> of type <class 'type'>
pick(3.x) <class 'sys.int_info'> of type <class 'type'>
...
这只是结果的一小部分。我不明白。对我来说,哪一个细节是错的也无济于事。以及如何解决这个问题。在
我见过:http://docs.python.org/3/library/pickle.html#what-can-be-pickled-and-unpickled但是如果我不能检测到代码中哪一行不能被pickle,这对我没有多大帮助。在
我的复杂对象中的代码按预期工作,最后运行生成的代码如下:
sys.modules['unum']
但在酸洗时,似乎“模块”没有按预期读取。在
一些背景来澄清我的意思。我曾经有过一些有用的程序,但突然就不起作用了。它可能是更新或其他更改资源。为他人工作而不是为我工作的程序。在
这是一个普遍的问题,所以我想开发一个程序来检查各种资源。各种资源的数量是巨大的。所以我有一个具有所有一般行为的父对象类。以及针对特定资源的尽可能小的细节类。在
这是在我的儿童资源课上完成的。在
这些资源必须使用不同的版本进行检查,例如python2.7或python3.3 如果使用Python2.7.5运行,则资源在需要Python2.7及更高版本时有效。所以支票必须比相等的值多一点。 这在自定义配置文件中被指定为单个语句。每个程序都有一个特定的配置文件,必须尽可能小才能使用。使用配置文件中的单个语句检查一个资源。在
一般类占代码的98%。具体的资源和配置只占代码的2%。所以很容易添加新的资源来检查,为新程序添加新的配置文件。在
此子资源:
class R_Sys(r_base.R_Base):
'''
doc : http://docs.python.org/3/library/sys.html#module-sys
sys.modules returns only a list of imported module
statement :
sys.modules['psutil'] # may return false (installed but not imported
but the statements :
import psutil
sys.modules['psutil'] # will return true, now psutil is imported
'''
allowed_names = ('modules', 'path', 'builtin_module_names', 'stdin')
allowed_keys_in_dict_config = ('name',)
allowed_operators = ("R_NONE", "=", 'installed') # installed only for modules
class_group = 'Sys'
module_used = sys
def __init__(self, check_type, group, name):
super(R_Sys, self).__init__(check_type, group, name)
由以下配置语句调用:
sc.analyse(r.R_Sys, c.ct('DETECT'), dict(name='path'))
可以成功地腌制。 但是使用config语句:
sc.analyse(r.R_Sys, c.ct('DETECT'),
dict(name='modules', tuplename='unum') )
它失败了。在
这意味着在我看来98%的主代码应该是可以的,否则第一个语句也会失败。在
子类中有类属性。这些都是正常工作所必需的。在第一个调用中,dump执行得很好。我还没装弹呢。在
dill
有一些很好的酸洗诊断工具,其中最好的是pickle跟踪(类似于您所实现的)。在让我们构建一个复杂的对象,并探索:
打开“pickle trace”:
^{pr2}$好的,
dill
可以对这个对象进行pickle…所以让我们更难一些。 我们先关闭追踪。在好了,现在
dill
失败了。那么失败的原因是什么呢? 如果我们深入研究我们的对象f
,我们可以看到所有未能pickle的对象。在嗯。那是很多。当然,不是所有这些对象都必须序列化,我们的对象才能序列化…但是至少其中一个导致了失败。在
自然要做的是看看我们的失败… 那么,会抛出什么错误呢?也许这会给你一个暗示。在
啊哈,
listiterator
是个坏东西。让我们重新打开“trace”来深入挖掘。在实际上,它停在
listiterator
。但是,请注意(就在上面),这个xrange
会进行pickle。所以,让我们把iter
替换为xrange
我们的对象现在又变酸了。在
dill
内置了许多其他pickle检测工具,包括跟踪指向哪个对象的方法(对于调试递归酸洗失败很有用)。在我相信
cloudpickle
也有一些类似的工具,用于pickle调试dill
,但是这两种情况下的主要工具都与您构建的类似。在相关问题 更多 >
编程相关推荐