Python __getinitargs__ 的 3 个备选方案
Python 3 alternatives for __getinitargs__
在 Python 3 中的 unpickling 期间,是否有足够短的方法来调用 class 的 __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__
在新样式classes中将被忽略,在Python3+中,所有classes只能是新样式class是的。有 __getnewargs__
但它只会将参数传递给 __new__
class 方法,这是不一样的。上述说明性示例的 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 在这方面不会轻易倒退,所以希望我遗漏了一些明显的东西。
编辑:用__getnewargs__
替换__getinitargs__
不能解决问题。
如果您希望 pickle
通过调用 Car(self.model, self.number)
来解开您的对象,通过 __init__
以与正常调用 Car
相同的方式进行初始化,然后告诉它在 __reduce__
method:
中这样做
def __reduce__(self):
return (Car, (self.model, self.number))
Demo.
在 Python 3 中的 unpickling 期间,是否有足够短的方法来调用 class 的 __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__
在新样式classes中将被忽略,在Python3+中,所有classes只能是新样式class是的。有 __getnewargs__
但它只会将参数传递给 __new__
class 方法,这是不一样的。上述说明性示例的 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 在这方面不会轻易倒退,所以希望我遗漏了一些明显的东西。
编辑:用__getnewargs__
替换__getinitargs__
不能解决问题。
如果您希望 pickle
通过调用 Car(self.model, self.number)
来解开您的对象,通过 __init__
以与正常调用 Car
相同的方式进行初始化,然后告诉它在 __reduce__
method:
def __reduce__(self):
return (Car, (self.model, self.number))
Demo.