Python中函数向菜单传递变量
我有一个叫做 menu() 的函数,它用来创建一个菜单,让我可以选择不同的功能。下面是这个函数的代码。
def menu():
x = raw_input("WOOF! What can POODLE fetch for you? ('--nothing' to exit): ")
if x == "--nothing":
sys.exit(0)
elif x == "--build":
populateCrawled(toCrawl)
graph = buildGraph(crawled)
index = buildIndex(graph)
ranks = computeRanks(graph)
menu()
elif x == "--dump":
saveFile(index, "index.txt")
saveFile(graph, "graph.txt")
saveFile(ranks, "ranks.txt")
menu()
elif x == "--restore":
index = loadFile("index.txt")
graph = loadFile("graph.txt")
ranks = loadFile("ranks.txt")
menu()
elif x == "--print":
print graph
print index
print ranks
menu()
elif x == "--help":
print "WOOF! POODLE Help Options"
print "--build Create the POODLE database"
print "--dump Save the POODLE database"
print "--restore Retrieve the POODLE database"
print "--print Show the POODLE database"
print "--help Show this help information"
menu()
elif x == "--search":
search(index, rankablePages)
else:
print "Help option not found"
menu()
seed = raw_input("Please enter the seed URL: ")
testSeed = "https://dunluce.infc.ulst.ac.uk/d11ga2/COM506/AssignmentB/test_index.html"
seed = testSeed
toCrawl=[seed]
crawled, graph, index, rankablePages = [], {}, {}, {}
MAX_DEPTH = 10
menu()
这些变量和字典都是全局声明的,但当我输入“--build”时,它确实能成功构建。但是当我接着输入“--print”时,就出现了一个错误,提示“UnboundLocalError: local variable 'graph' referenced before assignment”,意思是说在赋值之前就引用了这个局部变量 'graph'。
不过,如果我在构建之后立刻打印这些字典,它们是可以正常显示的。问题出在当 menu() 函数重新加载时,它丢失了这些值。我是不是应该使用一个循环,还是说我需要传递一些参数呢?
2 个回答
0
1
这些变量虽然是全局声明的,但这并没有什么帮助(不过要注意,你其实并没有真正把 ranks
定义为全局变量……),因为它们在局部也被声明了,局部的名字会遮住全局的名字。
每当你在一个函数内部写 spam = eggs
时,spam
就变成了一个局部变量。在这个函数里,任何地方出现的 spam
都指的是这个局部变量。
如果你想让某个变量是全局的,但又想给它赋值,你需要使用一个 global
声明。所以:
def menu():
global graph, index, ranks
# the rest of your code
不过,通常来说,最好的办法是停止使用全局变量。
一个选择是创建一个 类 来保存你的状态,把 menu
作为这个类的方法,并把 graph
和其他相关的变量作为这个类实例的属性。
但这里还有一个更简单的选择。你需要这些变量是全局的唯一原因是因为 menu
正在递归调用自己来模拟一个循环。这样做在 Python 中本身就不是个好主意,原因还有很多。(比如,如果你在菜单里转了大约 999 次,你会遇到递归错误。)如果你直接使用循环,而不是试图伪装成循环,你就可以使用局部变量了:
def menu(graph, index, ranks):
while True:
# the rest of your code except the menu() calls
# ...
crawled, graph, index, rankablePages = [], {}, {}, {}
menu(graph, index, ranks)