-1

我已经实现了一种编写和读取 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')orloadHash('./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 中工作?我正在使用参数解析器来获取文件名。

4

3 回答 3

4

首先,切勿使用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}
于 2012-06-26T20:53:42.473 回答
2

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

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

def saveHash(my_hash):
    # ...

def loadHash():
    # ...
    return my_hash

# Usage:
saveHash(my_hash)
my_hash = loadHash()
于 2012-06-26T20:55:27.300 回答
0

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

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

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

于 2012-06-26T20:52:52.020 回答