腌制不可刺的物体 [英] Pickling unpicklable objects

查看:82
本文介绍了腌制不可刺的物体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用pygame制作绘图程序,我想给用户一个选项,可以保存程序的确切状态,然后在以后重新加载它. 在这一点上,我保存了一份全局字典的副本,然后进行遍历,腌制每个对象. pygame中有些对象无法腌制,但可以转换为字符串并以这种方式腌制.我的代码已设置为执行此操作,但是其中一些不可拾取的对象已通过引用到达.换句话说,它们不在全局词典中,但是被全局词典中的对象引用.我想在此递归中对它们进行腌制,但是我不知道如何告诉pickle退回遇到问题的对象,对其进行更改,然后尝试再次对其进行腌制.我的代码真的很k脚,如果有其他更好的方法来完成我想做的事情,请告诉我.

I am making a drawing program with pygame in which I want to give the user an option of saving the exact state of the program and then reloading it at a later time. At this point I save a copy of my globals dict and then iterate through, pickling every object. There are some objects in pygame that cannot be pickled, but can be converted into strings and pickled that way. My code is set up to do this, but some of these unpicklable objects are being reached by reference. In other words, they aren't in the global dictionary, but they are referenced by objects in the global dictionary. I want to pickle them in this recursion, but I don't know how to tell pickle to return the object it had trouble with, change it, then try to pickle it again. My code is really very kludge, if there's a different, superior way to do what I'm trying to do, let me know.


surfaceStringHeader = 'PYGAME.SURFACE_CONVERTED:'
imageToStringFormat = 'RGBA'
def save_project(filename=None):
    assert filename != None, "Please specify path of project file"
    pickler = pickle.Pickler(file(filename,'w'))
    for key, value in globals().copy().iteritems():
        #There's a bit of a kludge statement here since I don't know how to 
        #access module type object directly
        if type(value) not in [type(sys),type(None)]   and \
        key not in ['__name__','value','key']          and \
        (key,value) not in pygame.__dict__.iteritems() and \
        (key,value) not in sys.__dict__.iteritems()    and \
        (key,value) not in pickle.__dict__.iteritems(): 
        #Perhaps I should add something to the above to reduce redundancy of
        #saving the program defaults?
            #Refromat unusable objects:
            if type(value)==pygame.Surface:
                valueString = pygame.image.tostring(value,imageToStringFormat)
                widthString = str(value.get_size()[0]).zfill(5)
                heightString = str(value.get_size()[1]).zfill(5)
                formattedValue = surfaceStringHeader+widthString+heightString+valueString
            else:
                formattedValue = value

            try:
                pickler.dump((key,formattedValue))
            except Exception as e:
                print key+':' + str(e)

def open_project(filename=None):
    assert filename != None, "Please specify path to project file"
    unpickler = pickle.Unpickler(file(filename,'r'))
    haventReachedEOF = False
    while haventReachedEOF:
        try:
            key,value = unpickler.load()
            #Rework the unpicklable objects stored 
            if type(value) == str and value[0:25]==surfaceStringHeader:
                value = pygame.image.frombuffer(value[36:],(int(value[26:31]),int(value[31:36])),imageToStringFormat)
            sys.modules['__main__'].__setattr__(key,value)
        except EOFError:
            haventReachedEOF = True

推荐答案

简而言之:不要这样做.

In short: Don't do this.

对应用程序中的所有内容进行处理很麻烦,并且可能会导致问题.从程序中获取所需的数据,并将其手动存储为适当的数据格式,然后通过从该数据创建所需的内容来加载它.

Pickling everything in your application is messy and likely to cause problems. Take the data you need from your program and store it in an appropriate data format manually, then load it by creating the things you need back from that data.

这篇关于腌制不可刺的物体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆