当前位置: 首页 > 面试题库 >

在尝试腌制对象时,为什么我的类定义__slots__时出错?

欧阳安晏
2023-03-14
问题内容

我正在尝试腌制我定义的(新式)类的对象。但我收到以下错误:

>>> with open('temp/connection.pickle','w') as f:
...   pickle.dump(c,f)
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/lib/python2.5/pickle.py", line 1362, in dump
    Pickler(file, protocol).dump(obj)
  File "/usr/lib/python2.5/pickle.py", line 224, in dump
    self.save(obj)
  File "/usr/lib/python2.5/pickle.py", line 331, in save
    self.save_reduce(obj=obj, *rv)
  File "/usr/lib/python2.5/pickle.py", line 419, in save_reduce
    save(state)
  File "/usr/lib/python2.5/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/usr/lib/python2.5/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/usr/lib/python2.5/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/usr/lib/python2.5/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/usr/lib/python2.5/copy_reg.py", line 76, in _reduce_ex
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled

我没有__slots__在课堂上明确定义。我做了隐式定义吗?我该如何解决?我需要定义__getstate__吗?


问题答案:

定义__slots__(而不是__getstate__)的类可以是您的祖先类,也可以是您的属性或项的类(或祖先类),直接或间接地:本质上,有
引用 中有任何对象的类具有您的对象将成为根,因为酸洗需要保存整个图形。

解决这个难题的一个简单方法是使用protocol
-1,这意味着“可以使用的最佳协议pickle”。默认值为基于ASCII的古老协议,该协议对__slots__vs施加了此限制__getstate__。考虑:

>>> class sic(object):
...   __slots__ = 'a', 'b'
... 
>>> import pickle
>>> pickle.dumps(sic(), -1)
'\x80\x02c__main__\nsic\nq\x00)\x81q\x01.'
>>> pickle.dumps(sic())
Traceback (most recent call last):
  [snip snip]
    raise TypeError("a class that defines __slots__ without "
TypeError: a class that defines __slots__ without defining __getstate__ cannot be pickled
>>>

正如你看到的,协议-1采取__slots__了事,而默认的协议给你看到了同样的异常。

协议的问题-1:它生成一个二进制字符串/文件,而不是像默认协议那样的ASCII字符串/文件;最终的腌制文件将无法通过足够古老的Python版本加载。除了关键优势外,优势还__slots__包括更紧凑的结果和更好的性能。

如果您被迫使用默认协议,则需要准确确定哪个类给您带来了麻烦以及原因。如果是这种情况,我们可以讨论策略(但如果您可以使用该-1协议,那就更好了,以至于不值得讨论;-),寻找麻烦的类/对象的简单代码检查被证明太复杂了(我在请注意一些基于深度复制的技巧,以获取整个图形的可用表示(以防您想知道)。



 类似资料:
  • 我正在使用Java8开发Spring Boot Version2,当我试图在“createTopic”方法中将一个新的列表对象添加到预定义的列表对象(即topicList)中时,我得到了一个错误。 ** TopicService.java ** ** 2020-04-15 19:52:27.172错误15312---[nio-8080-exec-2]O.A.C.C.C.[.[.[/].[dispa

  • 我的系统是LinuxMint18.3。Java版本“1.8.0_161”。当我使用命令“java-jar jenkins.war”启动jenkins时,一切正常。当我让詹金斯进入tomcat时,一切顺利。但当我试图使用命令“java-jar jenkins.war--httpPort=9090”启动jenkins时,我遇到了错误。你能帮我找到原因吗?

  • 我正在尽力导出我的javafx(11)项目,但似乎什么也做不到。我使用IntelliJ IDE,例如,让我们使用此项目:https://github.com/EveningSt3r/JFX-hotel-project.(我在30分钟内写下了这篇文章,但它很简单,并且满足了这个问题的目的) 当我使用IntelliJ的构建工件功能时:“fx:deploy不可用”我不知道如何使用jlink,并且所有在线

  • 致命异常:main java.lang.RuntimeException:无法启动活动组件Info{com.example.increative/com.example.increve.comments}:java.lang.ClassCastException:Android.os.Parcelable[]无法强制转换为Com.example.increve.MessageModel.Token

  • 问题内容: 与函数相反,类的主体在定义时执行: 出: 为什么会这样呢?它与/方法和类属性有关吗? 问题答案: *Python首次导入模块时, *所有操作 均在模块级别执行。函数体(和生成器表达体)在这里是 例外 ,而不是规则。Python执行所有操作以创建模块中包含的 对象 ;像Python中的所有内容一样,类是对象,函数也是。 类主体使用单独的代码对象的唯一原因是因为类主体是在单独的名称空间中执

  • 问题内容: 这是我的代码: 当我执行此操作时,将引发错误: 我确保它不是拼写错误,并且我没有拼错该函数的名称,所以为什么会出现NameError? 问题答案: 除非已定义函数,否则无法调用它。将块移动到文件的顶部,在导入的下面。 某些语言允许您在定义函数之前使用函数。例如,javascript将其称为“吊装”。但是Python并不是这些语言之一。 请注意,只要按 时间顺序 在使用前定义,就可以在比