gpt4 book ai didi

python - 使用从 SimpleNamespace 派生的类的 pickle.load 上的 TypeError

转载 作者:太空宇宙 更新时间:2023-11-03 15:43:08 27 4
gpt4 key购买 nike

考虑这段 Python(3.5 版)代码:

import pickle
from types import SimpleNamespace

class MyClass1(list):
def __init__(self, x):
self.append(x)

class MyClass2(SimpleNamespace):
def __init__(self, x):
self.x = x

a0 = SimpleNamespace(x=99)
a1 = MyClass1(99)
a2 = MyClass2(99)

print('* SimpleNamespace:', pickle.loads(pickle.dumps(a0)))
print('* MyClass1:', pickle.loads(pickle.dumps(a1)))
print('* MyClass2:', pickle.loads(pickle.dumps(a2)))

这对前两个(a0 和 a1)工作正常,但在处理 a2 时我得到一个错误:

* SimpleNamespace: namespace(x=99)
* MyClass1: [99]
Traceback (most recent call last):
File "./picktest.py", line 20, in <module>
print('* MyClass2:', pickle.loads(pickle.dumps(a2)))
TypeError: __init__() missing 1 required positional argument: 'x'

观察:

  • SimpleNamespace 可以 pickle。
  • 派生自不同类型 (list) 的类可以被(取消)pickled。
  • 如果派生自 SimpleNamespace 的类具有需要参数的 __init__,则无法对其进行 unpickled。 (错误发生在pickle.loads)

请注意,我尝试将 self.x = x 替换为 pass 并且没有任何改变。

除了在没有继承的情况下重新实现 MyClass2 之外,还有其他方法可以使这项工作正常进行吗?

最佳答案

问题是 SimpleNamespace 定义了一个 __reduce__pickle 使用它来取消 pickle 您的对象。但是,SimpleNamespace 中定义的 __reduce__ 与您的 __init__ 不一致。你可以定义你自己的 __reduce__ 来避开这个:

import pickle
from types import SimpleNamespace

class MyClass1(list):

def __init__(self, x):
self.append(x)

class MyClass2(SimpleNamespace):

def __init__(self, x):
self.x = x

def __reduce__(self):
return (self.__class__, (self.x,))

a0 = SimpleNamespace(x=99)
a1 = MyClass1(99)
a2 = MyClass2(99)

print('* SimpleNamespace:', pickle.loads(pickle.dumps(a0)))
print('* MyClass1:', pickle.loads(pickle.dumps(a1)))
print('* MyClass2:', pickle.loads(pickle.dumps(a2)))

关于python - 使用从 SimpleNamespace 派生的类的 pickle.load 上的 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51519351/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com