所以我尝试创建dict
的子类,使其成为1)不可变的,2)接受pickle数据,但是当它应该取消数据时,它会因错误而失败:TypeError: cannot convert dictionary update sequence element #0 to a sequence
这是我的代码:
>>> class Message(dict):
def __new__(cls, *args, **kwargs):
"""Create a new message object."""
if len(args) == 1 and isinstance(args[0], bytes):
args = (pickle.loads(args[0]),)
return super().__new__(cls, *args, **kwargs)
>>> Message({"a": 1})
{'a': 1}
>>> Message(pickle.dumps({"a": 1}))
Traceback (most recent call last):
File "<pyshell#99>", line 1, in <module>
Message(pickle.dumps({"a": 1}))
TypeError: cannot convert dictionary update sequence element #0 to a sequence
修改
我把它改为:
def __new__(cls, *args, **kwargs):
"""Create a new message object."""
if len(args) == 1 and isinstance(args[0], bytes):
args = (pickle.loads(args[0]),)
self = super().__new__(cls)
self.__init__(*args, **kwargs)
return self
但它仍然不起作用,所以__new__
- &gt; __init__
也没有帮助。
答案 0 :(得分:0)
您得到的错误是因为dict.__new__
没有按照您的想法行事;它总是返回一个新的空字典。
然后将参数传递给dict.__init__
,它将根据其参数更新self
(我们的dict子类)。
所以,唉,你做不到dict(pickle.dumps({'a':1})
。
作为一种解决方法,您可以在super().update()
中致电__new__
,并提供无操作__init__
,但我不会这样做。也许你真正想要的只是pickle.loads(...)
而不是MyFancySubclass(pickle.loads(...))
;
编辑 ,因为它显然不清楚,您的子类必须如下所示:
class MyDict(dict):
def __init__(self, *args, **kwargs):
pass # DO NOTHING!
def __new__(cls, *args, **kwargs):
self = super().__new__(cls)
self.update(get_some_data(args, kwargs)) # NOT __init__
return self