类变量字典未在python 2.7中使用pickle.dump保存 [英] Class variable dictionary not saving with pickle.dump in python 2.7

查看:78
本文介绍了类变量字典未在python 2.7中使用pickle.dump保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用pickle通过转储根来保存对象图.当我加载根目录时,它具有所有实例变量和连接的对象节点.但是,我将所有节点保存在字典类型的类变量中.在保存之前,该类变量已满,但是在我释放数据之后,该类变量为空.

I am using pickle to save an object graph by dumping the root. When I load the root it has all the instance variables and connected object nodes. However I am saving all the nodes in a class variable of type dictionary. The class variable is full before being saved but after I unpickle the data it is empty.

这是我正在使用的课程:

Here is the class I am using:

class Page():

    __crawled = {}

    def __init__(self, title = '', link = '', relatedURLs = []):
        self.__title = title
        self.__link = link
        self.__relatedURLs = relatedURLs
        self.__related = [] 

    @property
    def relatedURLs(self):
        return self.__relatedURLs

    @property
    def title(self):
        return self.__title

    @property
    def related(self):
        return self.__related

    @property
    def crawled(self):
        return self.__crawled

    def crawl(self,url):
        if url not in self.__crawled:
            webpage = urlopen(url).read()
            patFinderTitle = re.compile('<title>(.*)</title>')
            patFinderLink = re.compile('<link rel="canonical" href="([^"]*)" />')
            patFinderRelated = re.compile('<li><a href="([^"]*)"')

            findPatTitle = re.findall(patFinderTitle, webpage)
            findPatLink = re.findall(patFinderLink, webpage)
            findPatRelated = re.findall(patFinderRelated, webpage)
            newPage = Page(findPatTitle,findPatLink,findPatRelated)
            self.__related.append(newPage)
            self.__crawled[url] = newPage
        else:
            self.__related.append(self.__crawled[url])

    def crawlRelated(self):
        for link in self.__relatedURLs:
            self.crawl(link)

我这样保存它:

with open('medTwiceGraph.dat','w') as outf:
    pickle.dump(root,outf)

我这样加载它:

def loadGraph(filename): #returns root
    with open(filename,'r') as inf:
        return pickle.load(inf)

root = loadGraph('medTwiceGraph.dat')

除类变量__crawled之外的所有数据加载.

All the data loads except for the class variable __crawled.

我在做什么错了?

推荐答案

Python并不会真正腌制类对象.它只是保存它们的名称以及在哪里可以找到它们.从 pickle :

Python doesn't really pickle class objects. It simply saves their names and where to find them. From the documentation of pickle:

类似地,类通过命名引用进行腌制,因此相同 适用于解酸环境的限制.请注意,无 该课程的代码或数据被腌制,因此在以下示例中, 类属性attr在解开环境中未恢复:

Similarly, classes are pickled by named reference, so the same restrictions in the unpickling environment apply. Note that none of the class’s code or data is pickled, so in the following example the class attribute attr is not restored in the unpickling environment:

class Foo:
    attr = 'a class attr'

picklestring = pickle.dumps(Foo)

这些限制是为什么必须将可腌制的函数和类设为 在模块的顶层定义.

These restrictions are why picklable functions and classes must be defined in the top level of a module.

类似地,腌制类实例时,其类的代码和 数据不会与它们一起腌制.仅实例数据是 腌制这是有意完成的,因此您可以修复类中的错误或 向类添加方法,并仍然加载使用创建的对象 该类的早期版本.如果你打算长寿 会看到一个类的许多版本的对象,这可能是值得的 在对象中放置版本号,以便进行适当的转换 可以通过类的__setstate__()方法进行.

Similarly, when class instances are pickled, their class’s code and data are not pickled along with them. Only the instance data are pickled. This is done on purpose, so you can fix bugs in a class or add methods to the class and still load objects that were created with an earlier version of the class. If you plan to have long-lived objects that will see many versions of a class, it may be worthwhile to put a version number in the objects so that suitable conversions can be made by the class’s __setstate__() method.

在您的示例中,您可以解决将__crawled更改为实例属性或全局变量的问题.

In your example you could fix your problems changing __crawled to be an instance attribute or a global variable.

这篇关于类变量字典未在python 2.7中使用pickle.dump保存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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