pickle在新旧版本python中的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37407587/article/details/82177926

在运行github上deep-siamese-text-similarity 的代码时, 遇到args[0] from __newobj__ args has the wrong class 的错误, 在一个issue里找到了解决方法, 但是不知道为什么, 遂做了一点小实验做个验证. 在此记录.

python2.7

Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34) 
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class A():
... def __init__():
... self.a = 5
... 
>>> a = A()
>>> a.a
5
>>> class B(A):
... def __init__(self):
... self.b = 6
... 
>>> b = B()
>>> b.b
6
>>> b.a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: B instance has no attribute 'a'
>>> class C(A):
... def __init__(self):
... sup = super(C, self)
... sup.__init__()
... self.c = 7
... 
>>> c = C()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
TypeError: super() argument 1 must be type, not classobj
>>> # tips: `super` function can't be applied on old class 
>>> class A_n(object):
... def __init__(self):
... self.a = 8
... 
>>> class C(A_n):
... def __init__(self):
... sup = super(C, self)
... sup.__init__()
... self.c = 9
... 
>>> c = C()
>>> c.a
8
>>> c.c
9
>>> class D(A_n):
... def __init__(self):
... self.sup = super(D, self)
... self.sup.__init__()
... self.d = 10
... 
>>> d = D()
>>> d.a
8
>>> d.d
10
>>> import pickle
>>> pickle.dumps(c)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nC\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'a'\np6\nI8\nsS'c'\np7\nI9\nsb."
>>> pickle.dumps(d)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nD\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'a'\np6\nI8\nsS'd'\np7\nI10\nsS'sup'\np8\ng0\n(g1\ng2\nNtp9\nRp10\ng5\nbsb."
>>> 

python3.x

Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.4.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: class A():
   ...: def __init__(self):
   ...: self.a = 5
   ...:         

In [2]: class B(A):
   ...: def __init__(self):
   ...: sup = super(B, self)
   ...: sup.__init__()
   ...: self.b = 6
   ...:         

In [3]: a = A()

In [4]: a.a
Out[4]: 5

In [5]: b = B()

In [6]: b.a
Out[6]: 5

In [7]: class C(A):
   ...: def __init__(self):
   ...: self.sup = super(C, self)
   ...: self.sup.__init__()
   ...: self.c = 7
   ...:         

In [8]: c = C()

In [9]: c.a
Out[9]: 5

In [10]: import pickle

In [11]: pickle.dumps(b)
Out[11]: b'\x80\x03c__main__\nB\nq\x00)\x81q\x01}q\x02(X\x01\x00\x00\x00aq\x03K\x05X\x01\x00\x00\x00bq\x04K\x06ub.'

In [12]: pickle.dumps(c)
---------------------------------------------------------------------------
PicklingError Traceback (most recent call last)
<ipython-input-12-4523793c002f> in <module>()
----> 1 pickle.dumps(c)

PicklingError: args[0] from __newobj__ args has the wrong class

新旧版本的python对比发现, 2.7版本中, 使用pickle序列化包含super对象的实例是没有问题的, 但是在3.x版本中, 使用pickle序列化包含super对象的实例会报错.

猜你喜欢

转载自blog.csdn.net/m0_37407587/article/details/82177926