为什么Pickle没有像文档那样调用__new__?

时间:2016-04-17 02:31:29

标签: python deserialization instance pickle

documentation for Pickle具体说:

  

使用以下方法创建新式C类的实例:

obj = C.__new__(C, *args)

尝试利用这一点,我创建了一个没有实例属性或方法的单例:

class ZeroResultSentinel(object):
    instance = None
    def __new__(cls, *args):
        if not cls.instance:
            cls.instance = super(ZeroResultSentinel, cls).__new__(cls, *args)
        return cls.instance

(此类用于缓存层,以区分缓存中的无结果结果。)

单例工作得很好(每次调用ZeroResultSentinel()都会在内存中产生相同的实例,而ZeroResultSentinel() == ZeroResultSentinel()会计算为True)。而我可以 pickle和unpickle实例没有错误。但是,当我取消它时,我会得到一个不同的实例。所以我在__new__内放置了一个断点。我每次拨打ZeroResultSentinel()时都会遇到断点,但是当我取消腌制的ZeroResultSentinel时,我没有遇到断点。这与文档直接矛盾。我做错了什么,或文档不正确?

1 个答案:

答案 0 :(得分:3)

文档并没有真正说清楚,但您的Index, Child-Level,Parent-Level,Parent-Index 1,1,1,1 2,2,1,1 4,4,3,3 9,9,8,8 3,3,2,2 5,5,4,4 8,8,7,7 6,6,5,5 7,7,6,6 10,10,9,9 11,11,10,10 12,12,11,11 13,13,12,12 14,14,13,13 15,14,13,13 16,14,13,13 17,14,13,13 18,14,13,13 19,14,13,13 20,14,13,13 21,13,12,12 22,13,12,12 23,13,12,12 24,14,13,23 25,14,13,23 26,14,13,23 27,11,10,10 28,9,8,8 29,9,8,8 30,9,8,8 31,9,8,8 32,9,8,8 33,9,8,8 34,9,8,8 35,8,7,7 36,9,8,35 37,10,9,36 38,11,10,37 39,11,10,37 40,12,11,39 41,12,11,39 42,13,12,41 43,13,12,41 44,13,12,41 45,11,10,37 46,12,11,45 47,13,12,46 48,14,13,47 49,14,13,47 50,14,13,47 51,14,13,47 52,14,13,47 53,14,13,47 54,14,13,47 55,13,12,46 56,13,12,46 57,13,12,46 58,9,8,35 59,9,8,35 60,9,8,35 61,9,8,35 62,8,7,7 63,8,7,7 64,8,7,7 65,8,7,7 66,8,7,7 67,8,7,7 68,8,7,7 方法仅用于pickle协议2及以上版本:

__new__

在Python 2上,默认协议为0,因此如果您使用默认协议,则必须更改默认协议。