将Python字符串转换为原始格式

2024-05-19 12:35:05 发布

您现在位置:Python中文网/ 问答频道 /正文

class FrozenDict(dict):
    def __init__(self,default=None):
        if default: self.update(default)
    def __hash__(self):
        return id(self)


dictionary={FrozenDict({"dsa":"saas"}):"Hi"}

eval(str(dictionary))


TypeError: unhashable type: 'dict'

我正在尝试将字符串转换为它的“原始”形式,因此没有收到错误。字典的“原始”形式是{FrozenDict({"dsa":"saas"}):"Hi"}

像这样:

^{pr2}$

太棒了。。在

编辑:

OrderedDict似乎有用,有人知道为什么吗?在

编辑:

这是我试图加载使用酸洗负荷在

^{3}$

Tags: selfnonedefault编辑dictionaryifinitdef
3条回答

要创建“rawform”,您需要重写__repr__

class FrozenDict(dict):
    def __init__(self,default=None):
        if default: self.update(default)
    def __hash__(self):
        return id(self)
    def __repr__(self):
        return "FrozenDict(%s)" % dict.__repr__(self)


print FrozenDict({"dsa":"saas"})

dictionary={FrozenDict({"dsa":"saas"}):"Hi"}

print eval(str(dictionary))

我得到的结果是:

^{pr2}$

为了这个目的,你有什么理由不能改成{}?在

import cPickle as pickle
# This can't be `eval`d, but...
string = pickle.dumps(dictionary)
# ... you can use it to get back the original object
obj = pickle.loads(string)

当然,它没有使用eval,但是如果可以避免使用eval,那么就应该这样做。在

你所做的有几个问题。在

首先,您的eval不起作用的原因是您没有重写您的FrozenDict类中的__repr__方法,因此{}生成的是一个常规字典而不是一个新的FrozenDict,并且在尝试将其用作字典键时出现错误。这相对容易解决:

def __repr__(self):
    return "FrozenDict({})".format(super(FrozenDict, self).__repr__())

{{cd7}你可以用它来重新创建你的cd6}代码。在

但是,还有一些其他问题不能解决。例如,当前可以使用哈希不同的字典,即使它们比较为相等:

^{pr2}$

这使得在哈希表中无法匹配冻结字典,如果插入时使用的对象不完全相同。在

更好的方法可能是根据字典中的键和值计算哈希。这样做会更好:

def __hash__(self):
    return hash(tuple(sorted(self.items()))

但是,现在您将遇到另一个问题:您的字典是可变的,如果您添加或删除其中的值,它的哈希可能会更改。这很糟糕:

a = FrozenDict()
d = {a: "a"}

a["foo"] = "bar"

d[a]            # raises a KeyError!
d[FrozenDict()] # perhaps surprisingly, so does this!

要解决这个问题,您可能需要重写__setitem____delitem__和{},以便在调用它们时引发异常。我想,如果您知道在将值添加到字典后不会修改这些值,可以跳过这一步,但是如果您希望您的类更普遍地有用,则有必要这样做。可能还有一些其他的突变方法我也忘了。在

相关问题 更多 >