繁体   English   中英

为什么Ellipsis和NotImplemented不能被腌制?

[英]Why can't Ellipsis and NotImplemented be pickled?

我很惊讶地发现python(版本3.2.2)拒绝挑选一个对象,因为它的dict包含对Ellipsis的引用。 在其他内置常量中 ,pickle很乐意使用FalseTrueNone ,正如pickle文档中明确指出的那样,但也有NotImplemented上的NotImplemented

Python 3.2.2 (default, Sep  5 2011, 21:17:14) 
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.dumps(True)
b'\x80\x03\x88.'
>>> pickle.dumps(False)
b'\x80\x03\x89.'
>>> pickle.dumps(None)
b'\x80\x03N.'
>>> pickle.dumps(Ellipsis)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'ellipsis'>: attribute lookup builtins.ellipsis failed
>>> pickle.dumps(NotImplemented)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class 'NotImplementedType'>: attribute lookup builtins.NotImplementedType failed

为了完整性,对于不太有用的内置常量, __debug__只是一个bool,所以没有问题; copyrightlicensecredits工作(其类型为site._Printer ); quitexit不(它们的类型是site.Quitter ,因为它在函数内定义而无法找到)。

任何人都可以解释为什么这是 - 当然, EllipsisNotImplemented不仅仅被忽视了吗? 我能找到的唯一相关信息就是这个bug ,它抱怨NoneType (即type(None) )不可选。 其中一位评论者提到, type(Ellipsis)type(NotImplemented)未实现type(NotImplemented)不能被腌制,显然没有注意到他们的实例也不能。

python绝对没有理由没有像EllipsisNotImplemented这样的东西,并且坦率地说没有它们可选择性地导致python作为并行/异步语言的脆弱性。 你可以用dill来腌制这些类型的物品,这是pickle的替代品。 是的,我知道这是一个温和的咆哮,但我认为你的目标代码中的NotImplemented不应该阻止你使用multiprocessing或来自并行python的其他...或者保存你的python会话的状态以便以后使用… 管他呢。

Python 3.2.5 (default, May 19 2013, 14:25:55) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import dill
>>> dill.dumps(True)
b'\x80\x03\x88.'
>>> dill.dumps(False)
b'\x80\x03\x89.'
>>> dill.dumps(None)
b'\x80\x03N.'
>>> dill.dumps(Ellipsis)
b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x08\x00\x00\x00Ellipsisq\x01\x85q\x02Rq\x03.'
>>> dill.dumps(NotImplemented)
b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x0e\x00\x00\x00NotImplementedq\x01\x85q\x02Rq\x03.'

在这里获取dillhttps//github.com/uqfoundation/dill

引用文档

可以腌制以下类型:

  • 无,真,假
  • 整数,浮点数,复数
  • 字符串,字节,字节数组
  • 仅包含可选对象的元组,列表,集和词典
  • 在模块顶层定义的函数
  • 在模块顶层定义的内置函数
  • 在模块顶层定义的类
  • 这些类的实例__dict__或__setstate __()是可选的(有关详细信息,请参阅Pickling Class Instances一节)

有问题的两个对象EllipsisNotImplemented不符合这些规则中的任何一个,因此无法进行pickle。

我怀疑没有更好的理由不在第一条规则中包含所有内置常量,除了没有人看到它的必要性。 如果您真的认为pickle应该支持,请考虑发布功能请求(更好地带来令人信服的用例!)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM