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

时间:2012-01-23 14:34:31

标签: python pickle

我很惊讶地发现python(版本3.2.2)拒绝挑选一个对象,因为它的dict包含对Ellipsis的引用。在其他built-in constants中,pickle很高兴与FalseTrueNone一起工作,如pickle documentation中明确说明的那样,但this bug上的窒息1}}。

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 只是一个bool,所以没有问题; __debug__copyrightlicense工作(其类型为credits); site._Printerquit没有(他们的类型为exit,因为它是在函数中定义的,所以找不到它。)

任何人都可以解释为什么这样做 - 肯定site.QuitterEllipsis不仅仅被忽视了吗?我能找到的唯一相关信息是{{3}},它抱怨NotImplemented(即NoneType)不可挑选。其中一位评论者提到type(None)type(Ellipsis)无法被剔除,显然没有注意到他们的实例也不会被腌制。

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

引用documentation

  

可以腌制以下类型:

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

有问题的两个对象EllipsisNotImplemented不符合这些规则,因此无法进行腌制。

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