【发布时间】:2018-05-12 16:06:31
【问题描述】:
在 Python 3 的 unpickling 期间,是否有足够短的方法来调用类的 __init__ 构造函数?通常的方法是使用__getinitargs__ 像这样
from __future__ import print_function
import pickle
class Car:
def __init__(self, model, number):
self.model = model
self.number = number
print("constructed with", model, number)
# many other things to do
def __getstate__(self):
# intentionally returns None
pass
def __setstate__(self, state):
pass
def __getinitargs__(self):
# save some information when pickling
# (will be passed to the constructor upon unpickling)
return self.model, self.number
c = Car("toyota", 1234)
d = pickle.loads(pickle.dumps(c))
print("reconstructed with", d.model, d.number)
但是,__getinitargs__ 在新样式类中将被忽略,在 Python 3+ 中,所有类只能是新样式类。有__getnewargs__,但它只会将参数传递给不一样的__new__ 类方法。上述说明性示例的 python 2 调用将导致
>> constructed with toyota 1234
>> constructed with toyota 1234
>> reconstructed with toyota 1234
虽然 python 3 调用会出错
>> constructed with toyota 1234
Traceback (most recent call last):
File "test.py", line 26, in <module>
print("reconstructed with", d.model, d.number)
AttributeError: 'Car' object has no attribute 'model'
并忽略__getinitargs__ 方法。
我认为 Python 3 在这方面不会轻易退步,所以希望我遗漏了一些明显的东西。
编辑:将__getinitargs__ 替换为__getnewargs__ 并不能解决问题。
【问题讨论】:
-
为什么首先需要提供
__getinitargs__?您可以在此处删除__getstate__和__setstate__和__getinitargs__方法,它会正常工作。 -
这是一个更复杂对象的简化示例。该示例的重点是说明python 2中通常使用的方法。
标签: python python-3.x pickle