将Python字符串转换为原始形式
我正在尝试将字符串转换为它的“原始”形式,所以我没有得到错误。字典的“原始”形式是将Python字符串转换为原始形式,python,Python,我正在尝试将字符串转换为它的“原始”形式,所以我没有得到错误。字典的“原始”形式是{FrozenDict({“dsa”:“saas”}):“Hi”} 大概是这样的: class FrozenDict(dict): def __init__(self,default=None): if default: self.update(default) def __hash__(self): return id(self) dictionary={Fro
{FrozenDict({“dsa”:“saas”}):“Hi”}
大概是这样的:
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'
太棒了
编辑:
OrderedDict似乎有效,有人知道为什么吗
编辑:
这就是我试图使用pickle.loads加载的内容
eval(rawform(dictionary))
出于这个目的,您有什么理由不能
pickle
it来代替它吗
S'{\'Source\': {\'CollideObjects\': [], \'Depth\': 0, \'Events\': OrderedDict([(({\'function\': \'bi_create\', \'class\': \'\', \'name\': \'Create\'}, 0), {{\'data\': {\'raw\': \'Set saddasdsadsa to: (,)\', \'data\': {u\'function\': u\'asddsaadsasddsasdasdasddsasdasda(x=None,y=None)\', u\'src\': u\'GUI\\\\movetoxy.xml\', \'code\': u\'\\nreal=[0,0]\\ncurrent=self.sdsdadsaadssd()\\nif x!=None:\\n\\treal[0]=float(x)\\nelse:\\n\\treal[0]=current[1]\\nif y!=None:\\n\\treal[1]=float(y)\\nelse:\\n\\treal[1]=current[1]\\nself.SetPos(*real)\\n\', \'return\': u"\'Set Position to: (\'+str(x)+\',\'+str(y)+\')\'", u\'title\': u\'Set Position\', u\'image\': u\'modules\\\\Core\\\\images\\\\pos.png\', \'dddddddddd\': u\'self.SetPosition(,)\', \'html\': u\'C:\\\\sadsdadsad\\\\dsasasddsa\\\\modules\\\\Core\\\\GUI\\\\movetoxy.xml\', \'apply\': {\'name\': \'Self\', \'value\': \'\'}, u\'holder\': u\'False\', u\'class\': u\'object\'}, \'dialog\': u\'Set Position\', \'name_var\': {u\'y\': {\'class\': u\'wxTextCtrl\', \'value\': u\'\'}, u\'x\': {\'class\': u\'wxTextCtrl\', \'value\': u\'\'}}}}: {}})]), \'Sprite\': \'\'}, \'Window\': \'\', \'Type\': \'Object\', \'Name\': u\'Object1\', \'Id\': 1}'
当然,它没有使用eval
,但是如果可以避免使用eval
,那么应该避免使用eval
。要创建“rawform”,您需要覆盖\u repr\u
:
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)
我得到的结果是:
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))
你所做的有几个问题 首先,您的
eval
不起作用的原因是,您没有在FrozenDict
类中重写\uu repr\uuu
方法,因此eval
正在生成一个常规字典,而不是一个新的FrozenDict
,并在尝试将其用作字典键时出错。这相对容易修复:
FrozenDict({'dsa': 'saas'})
{FrozenDict({'dsa': 'saas'}): 'Hi'}
这将允许您使用对象的str
或repr
作为Python代码来重新创建它
然而,还有一些其他问题,这并不能解决。例如,当前您可以使用不同的字典进行散列,即使它们的比较结果相同:
def __repr__(self):
return "FrozenDict({})".format(super(FrozenDict, self).__repr__())
如果插入时使用的对象不完全相同,则无法在哈希表中匹配冻结的词典
更好的方法可能是基于字典中的键和值计算哈希。这样做会更好:
a = FrozenDict({"foo":"bar"})
b = FrozenDict({"foo":"bar"})
a == b # True!
hash(a) == hash(b) # False!
然而,现在您将遇到另一个问题:您的字典是可变的,如果您在其中添加或删除值,它的哈希值可能会改变。这是非常糟糕的:
def __hash__(self):
return hash(tuple(sorted(self.items()))
要解决此问题,您可能需要覆盖
\uuuu setitem\uuuuuuuuuuuuuu
、\uuuuuuu delitem\uuuuuu
和update
以在调用异常时引发异常。我想如果您知道在将值添加到字典后不会修改这些值,您可以跳过这一步,但是如果您希望您的类更普遍地有用,那么这是必要的。可能还有一些其他的突变方法我也忘记了。不要只返回id(self)
作为\uuuuuuuuuuuu散列
;这使得你的钥匙再也找不到了。嗯,我从网上得到的,你对我应该改什么有什么建议吗?看看\uuuuuu hash\uuuuuu
方法应该做什么。你需要考虑包含的键和值的散列值,并且你必须确保这些值也是可散列的。我实际上是将字典存储在sqlite3表中,当我从表中加载字典时,我得到,TypeError:必须是字符串,而不是unicode
,您知道解决此问题的最佳方法吗?也许您可以包括一个您遇到问题的数据示例,然后我们可以更容易地诊断:-)@AA:听起来您可能想要一个BLOB类型的列,而不是在数据库中编码文本。@AA:asqlite
text列是unicode值。您也可以考虑JSON来存储这些。代码>导入json;json.dumps(字典);JSON库可以处理Unicode和字节字符串输入。否则,你可以选择使用BLOB类型,或者在取消勾选之前将unicode转换回字节字符串。谢谢大家,但我会接受marc的答案,因为这似乎是一个快速解决方案。不过我真的很感谢你的帮助。
a = FrozenDict()
d = {a: "a"}
a["foo"] = "bar"
d[a] # raises a KeyError!
d[FrozenDict()] # perhaps surprisingly, so does this!