2014-11-03 6 views
0

У меня есть функция, menu(), которая создает меню для навигации и вызова функций. вот функция.Переменная Python, передающая функции в меню

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: локальная переменная ' граф ", на который ссылаются до присвоения

Однако, если я напечатаю эти словари сразу после строительства, они печатаются хорошо. Когда перезагружается меню(), оно теряет эти значения. Должен ли я использовать цикл while или мне нужно выполнить некоторую передачу параметров?

+0

Лучшим способом структурирования меню является сохранение всех опций в качестве ключей в словаре со значениями, являющимися функциями, которые выполняют функции. Затем весь код меню может быть 'if option в параметрах: options [option](); else: напечатать «Invalid input!» ' – whereswalden

ответ

1

Тот факт, что эти переменные объявлены глобально Безразлично Помогите (хотя обратите внимание, что вы не сделали фактически определяют ranks глобально ...), потому что они также объявлены локально, а локальные имена скрывают глобальные.

Всякий раз, когда вы пишете spam = eggs в теле функции, которая делает spam локальной переменной, и в функции появляется spam, она ссылается на эту локальную переменную.

Если вы хотите сделать что-то глобальное, но все же сможете назначить ему, вам понадобится global statement. Итак:

def menu(): 
    global graph, index, ranks 
    # the rest of your code 

Но, как обычно, лучшим решением является прекращение использования глобальных переменных.

Одним из вариантов создания класса держать свое состояние, сделать menu метод этого класса, и сделать и друзей атрибутов экземпляров класса.

Но здесь есть еще более простой вариант. Единственная причина, по которой эти переменные должны быть глобальными, состоит в том, что 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) 
0

Вы должны объявить график (и любой другой переменной, меню следует использовать наружно) как глобальная:

def menu(): 
    global graph 

    #rest of the code 

вы можете прочитать больше о глобалов here

Смежные вопросы