我已经实现了一种编写和读取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中吗?我使用参数解析器来获取文件名。
答案 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()