在Python中保存和加载字典

时间:2012-06-26 20:48:48

标签: python dictionary

我已经实现了一种编写和读取python字典的简单方法,但是,我无法理解为什么它不能作为函数工作。

要保存字典,请使用以下命令:

def saveHash():
     print "Saving hash file to ./savedHash"
     f = open('savedHash','w')
     f.write(str(my_hash))
     f.close()
     print "Save Successfull"

saveHash()

这完全没问题。现在在我做的脚本中加载我的字典:

def loadHash(name):
     print "Loading hash file %s" % (name)
     f = open(name,'r')
     my_hash = eval(f.read())
     f.close()
     print "Hash loaded"

loadHash('savedHash')

问题是它在我运行的脚本中似乎不起作用,但它可以在shell中运行。如果我在目录savedHash中有/home/dan/并在该目录中打开python shell,则运行loadHash('savedHash')loadHash('./savedHash')loadHash('/home/dan/savedHash')它不会填充字典/哈希值。当我random.choice(my_hash.keys())时它失败并返回此错误消息:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/projects/dan/software/Python-2.7.2/Lib/random.py", line 274, in choice
    return seq[int(self.random() * len(seq))]  # raises IndexError if seq is empty
IndexError: list index out of range

但是,如果我按命令运行命令:

>>> f = open(name,'r')
>>> my_hash = eval(f.read())
>>> f.close()

我可以输入print random.choice(my_hash.keys())并从中获取值。有人知道为什么它不会在脚本中工作但它会在shell中吗?我使用参数解析器来获取文件名。

3 个答案:

答案 0 :(得分:3)

首先,不要使用来自不受信任来源(如文件)的eval

我建议使用json存储字典:

>>> import json
>>> d = {'a': 3}
>>> with open('data.txt', 'w') as fobj:
...   json.dump(d, fobj)
... 
>>> with open('data.txt') as fobj:
...   d2 = json.load(fobj)
... 
>>> d2
{u'a': 3}

答案 1 :(得分:2)

这是因为在save函数中,my_hash被假定为全局的,并且取自全局命名空间,这正是您所期望的。但是,第二个函数不知道你在谈论全局变量。因此,您应该添加到函数的顶部global my_hash

更好的解决方案是将哈希作为参数传递给函数以保存它。并在加载时返回:

def saveHash(my_hash):
    # ...

def loadHash():
    # ...
    return my_hash

# Usage:
saveHash(my_hash)
my_hash = loadHash()

答案 2 :(得分:0)

您的loadHash()函数不会返回任何内容,因此当函数结束时myHash变量会消失。

如果您尝试填充全局变量myHash,正如其他答案中所指出的那样,您需要在函数中包含行global myHash。另请参阅尽可能避免全局变量的原因。

另请参阅其他答案中有关避免eval()

的说明