【发布时间】:2012-01-23 14:34:31
【问题描述】:
我惊讶地发现 python(3.2.2 版)拒绝腌制一个对象,因为它的 dict 包含对 Ellipsis 的引用。在其他built-in constants 中,pickle 很高兴与False、True 和None 合作,正如pickle documentation 中明确指出的那样,但也对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__ 只是一个布尔值,所以不会引起任何问题; copyright、license 和 credits 工作(它们的类型是 site._Printer); quit 和 exit 没有(它们的类型是 site.Quitter,无法找到,因为它是在函数内部定义的)。
谁能解释为什么会这样?Ellipsis 和 NotImplemented 肯定没有被忽视?我能找到的唯一相关信息是this bug,它抱怨NoneType(即type(None))不可腌制。其中一位评论者提到 type(Ellipsis) 和 type(NotImplemented) 不能被腌制,显然没有注意到它们的实例也不能被腌制。
【问题讨论】:
-
奇怪的遗漏,尽管有人可能会争辩说你不应该从一开始就保留对这些值的引用。
-
@Inderdial:我的特定用例是在一个容器中,该容器跟踪已访问的切片。由于切片可以腌制,Ellipsis(实际上只是一种特殊的切片)不能腌制似乎很奇怪。存储对
NotImplemented的引用可能不太有用,尽管我可以想象有人可能会想要它用于某种复杂的比较方案。 -
@James - 严格来说,
Ellipsis不是一种特殊的切片,但它的解释绝对是用户定义的。在 Numpy 中,它更像是一个由零个或多个切片组成的序列,自动确定。