也许试试这个代码。首先,您必须将文件(用零)填充为至少原始大小,可以更大(或者您可以更改一些代码以使其没有必要)。
我修改了函数 _Unpickler.load() 以在异常时不终止,并在 unpickling 失败时返回其堆栈。堆栈似乎是一个包含属性名称和值的列表,因此使用setattr() 您可以将它们分配给创建的对象。
如果read=False,我的示例创建一个对象来腌制,如果read=True,则取消腌制可能损坏的文件。
import pickle
read = False # run once with False, then corrupt file and change to True
class AClass:
def __init__(unpickler, a, b, c):
unpickler.a = a
unpickler.b = b
unpickler.c = c
def load(unpickler):
"""Read a pickled object representation from the open file.
Return the reconstituted object hierarchy specified in the file.
"""
# Check whether Unpickler was initialized correctly. This is
# only needed to mimic the behavior of _pickle.Unpickler.dump().
if not hasattr(unpickler, "_file_read"):
raise pickle.UnpicklingError("Unpickler.__init__() was not called by "
"%s.__init__()" % (unpickler.__class__.__name__,))
unpickler._unframer = pickle._Unframer(unpickler._file_read, unpickler._file_readline)
unpickler.read = unpickler._unframer.read
unpickler.readline = unpickler._unframer.readline
unpickler.metastack = []
unpickler.stack = []
unpickler.append = unpickler.stack.append
unpickler.proto = 0
read = unpickler.read
dispatch = unpickler.dispatch
try:
while True:
key = read(1)
if not key:
return unpickler.stack
#raise EOFError
assert isinstance(key, pickle.bytes_types)
try:
dispatch[key[0]](unpickler)
except KeyError as e:
print("KeyError")
#dispatch[NONE[0]](unpickler)
except ValueError as e:
print("ValueError")
except pickle._Stop as stopinst:
print("Stop raised")
print(stopinst.value)
return stopinst.value
if not read:
# create an object and save it
obj = AClass(1,2,3)
with open("obj.pkl", 'wb') as outFile:
pickle.dump(obj, outFile, pickle.HIGHEST_PROTOCOL)
else:
# open the object
with (open("obj.pkl", "rb")) as inFile:
try:
unpickler = pickle._Unpickler(inFile)
obj = load(unpickler)
except Exception as e:
print(e)
# a list will be returned, if the unpickling fails
if isinstance(obj, list):
l = obj
print(l)
i = 0
obj = AClass(0,0,0)
while i < len(l)-1:
setattr(obj, l[i], l[i+1])
i += 2
print(obj.a, obj.b, obj.c)