python: локальная переменная, на которую ссылаются до ошибки присваивания - PullRequest
0 голосов
/ 03 ноября 2011

Я заканчиваю текстовую игру для введения в класс Python.Это не завершено, но я работал над функцией main_menu и функциями, вызываемыми внутри функции main_menu, когда столкнулся с этим сообщением об ошибке.Я сталкивался с этой ошибкой несколько раз в моем опыте обучения, и она обычно приписывалась основной ошибке при назначении переменных, но эта ошибка ставит меня в тупик ... Это рассматриваемый скрипт (строки в traceback прокомментированы в BOLD ):

import random
from sys import exit


# Item variables
coal = ('Coal', 'some coal which can be used in a furnace.')
eng_key = ('Key', 'a key to a house.')
bomb = ('Bomb', 'a combustible device which creates a powerfull explosion. Possibly used for demolition...')
tonic = ('Tonic', 'a weak healing tonic. Adds \'5\' health points.')
sTonic = ('Super Tonic', 'a strong healing tonic. Adds \'10\' health points.')


# LOCATIONS
# Below are the possible locations you can 'travel' to, along with a title (first item in tuple), a description, any items that might be found in the location which can be discovered and entered into 'inventory' through 'search' command
# location variable = (title, description, item for discovery)
sub_base = ('Sub-Base', 'This is DeepBlue\'s base of operations in the Atlantis excavation zone. Your submarine is docked ahead', 'nothing useful here.')
cave = ('Underwater Cave', 'You have entered the mouth of an underwater cave with your sub.', 'nothing useful here.')
cemetery = ('Cemetery Chamber', 'You are in a large chamber within the cave. This seems to be a cemetery. There are symmetrically lined mounds of dirt, with obelisks at the head.', 'nothing useful here.')
city_gate = ('City Gate', 'You stand at a crossroad of sorts, at the bottom of an upward sloping ramp.', 'nothing useful here.')
city_outskirts = ('City Outskirts', 'You find yourself just outside the city walls.', 'nothing useful here.')
castle_outskirts = ('Rear of Castle Ruins', 'You are standing at the rear of the castle ruins. There is a layer of rubble blocking the way, but you can clearly see a passage leading inside. Perhaps you can devise a way to move it...', 'nothing useful here.')
castle_inside = ('Inside the Grand Castle of Atlantis', 'You have made it inside of the castle. All the advanced knowledge of the Atlanteans is at your disposal.', 'nothing useful here.')
city_block0 = ('Beginning of Main Avenue in City', 'You are standing at the beginning of the main avenue of the city.', 'nothing useful here.')
ruins1 = ('Rubble of Dilapidated House', 'You are standing in the middle of the ruins of what seems to have been a house.', tonic)
mystic_house = ('Mystic House', 'You are standing inside the city Mystic\'s house.', sTonic)
city_block1 = ('Second Block in City', 'You have moved to the second block of the city\'s main avenue.', 'nothing useful here.')
abandoned_house = ('Abandoned House', 'You are standing in the middle of an abandoned house.', eng_key)
blacksmith_house = ('Blacksmith\'s House', 'You are standing in what seems to be a blacksmith\'s building. There is a furnace, iron ore, smith\'s tools and various components for making swords. No coal though...', 'nothing useful here. But with the right items, something can be created here...')
city_block2 = ('Third Block in City', 'You have moved to the third block of the city\'s main avenue.', 'nothing useful here.')
marketplace = ('Abandoned Marketplace', 'You are standing in the middle of an abandoned marketplace. There might be some useful items laying around...', coal)
engineer_house = ('Engineer\'s House', 'You are standing in the engineer\'s house. There might be some useful items lying around...', bomb)
castle_main = ('Castle Main Entrance', 'You are standing in front of the main entrance of a huge castle. The grand entrance is blocked off by massive amounts of rubble. There must be another way in...', 'nothing useful here.')


# ITEMS
# below are the items which may be added to the inventory
items = {
    coal: (engineer_house,), 
    eng_key: (engineer_house,), 
    bomb: (castle_inside,),
    tonic: ('anywhere',),
    sTonic: ('anywhere',)
}


# INTERACTIONS(location-based)
# below is a dictionary of events. Each location has certain events which can only take place there.
# interactions dictionary = {location: (use+item response, search response)}
lEvents = {sub_base: (cave,),
    cave: (sub_base, cemetery, city_gate),
    cemetery: (cave, city_outskirts),
    city_gate: (cave, city_outskirts, city_block0),
    city_outskirts: (cemetery, castle_outskirts, city_gate),
    castle_outskirts: (city_outskirts,castle_inside),
    castle_inside: (castle_outskirts,),
    city_block0: (city_gate, ruins1, mystic_house, city_block1),
    ruins1: (city_block0,),
    mystic_house: (city_block0,),
    city_block1: (city_block0, abandoned_house, blacksmith_house, city_block2),
    abandoned_house: (city_block1,),
    blacksmith_house: (city_block1,),
    city_block2: (city_block1, marketplace, engineer_house, castle_main),
    marketplace: (city_block2,),
    engineer_house: (city_block2,),
    castle_main: (city_block2,)
}


# TRAVEL OPTIONS
# Below is a dictionary outlining the possible places to travel to depending on where you are currently located, this peice is essential to the travel function
travelOpt = {
    sub_base: (cave,),
    cave: (sub_base, cemetery, city_gate),
    cemetery: (cave, city_outskirts),
    city_gate: (cave, city_outskirts, city_block0),
    city_outskirts: (cemetery, castle_outskirts, city_gate),
    castle_outskirts: (city_outskirts,castle_inside),
    castle_inside: (castle_outskirts,),
    city_block0: (city_gate, ruins1, mystic_house, city_block1),
    ruins1: (city_block0,),
    mystic_house: (city_block0,),
    city_block1: (city_block0, abandoned_house, blacksmith_house, city_block2),
    abandoned_house: (city_block1,),
    blacksmith_house: (city_block1,),
    city_block2: (city_block1, marketplace, engineer_house, castle_main),
    marketplace: (city_block2,),
    engineer_house: (city_block2,),
    castle_main: (city_block2,)
}


def eHouseAccess(action, location, eHouse):
    if eHouse == 'locked':
        print "The door is locked! You need to find a key for this door."
        travel(location)
    else:
        location = travelOpt[location][action - 1]
        travel(location)


def cInsideAccess(action, location, cInside):
    if cInside == 'blocked':
        print "The path is blocked by rubble! You need to find a way to clear the rubble."
        travel(location)
    else:
        location = travelOpt[location][action - 1]
        travel(location)


def travel(location):
    while True:
        print "You are in the", location[0]+"." 
        print location[1]
        print 'You can travel to:'

        for (i, t) in enumerate(travelOpt[location]):
            print i + 1, t[0]

        action = raw_input("Pick a destination, or enter 'menu' for the main menu: ")
        if action == 'menu':
            main_menu(location, inventory, items)
        else:
            action = int(action)      
        if travelOpt[location][action - 1] == engineer_house:
            eHouseAccess(action, location, eHouse)
        elif travelOpt[location][action - 1] == castle_inside:
            cInsideAccess(action, location, cInside)
        else:
            location = travelOpt[location][action - 1]


def main_menu(location, inventory, items):
    travel = travel(location) # **this is line 133**
    invtry = showInv(inventory)
    use = use(items, inventory)
    quit = exit(0)
    while True:
        print "You are in the", location[0]
        menu_list = [('Travel', travel), ('Inventory', invtry), ('Use', use), ('Search', search), ('Map', map), ('Quit', quit)]
        print "Choose one:"
        for (num, t) in enumerate(menu_list):
            print num + 1, t[0]
        main_choice = int(raw_input("> "))
        action = menu_list[main_choice - 1]
        action[1]


def search(location):
    pass


def map(location):
    pass


def showInv(inventory):
    if inventory == []:
        print "Your inventory is empty"
        inv = 'empty'
        return inv
    else:
        for (num, i) in enumerate(inventory):
            print num + 1, i
        inv = inventory
        return inv

def use(items, inventory):
    a = showInv(inventory)
    if a == 'empty':
        print "There is nothing to use."
    else:
        showInv(inventory)
        uItem = int(raw_input("Choose an item to use: "))


location = sub_base
inventory = []
eHouse = 'locked'
cInside = 'blocked'
hp = 20

map = """
Key:
    * = indicates a point of entry
            ______ ______
           |Castle|Castle|
           |Outsk-|      |
           |irts         |
        ___|**____|__**__|
       | City |   |      |
       |Outsk-|   | City |
       | irts |   |      |
  _____|*____*|___|*_____|
 |       |  |       |
 | Grave |  | City  |
 | Yard  |  | Gates |
 |_____**|__|*______|
      |       |
      | Cave  |
      |       |
      |__**___|
      |       |
      | Sub-  |
      | Base  |
      |_______|
"""


cityMap = """
Key:
    * = indicates a point of entry
            ________
           |        |
           | Castle |
           |        |
     ______|___**___|________
    |      |  City  | Engin- |
    |Market|  Block | eer    |
    |Place *    3   * House  |
    |______|___  ___|________|
    |Aband-|  City  | Black- |
    | oned |  Block | smith  |
    |House *    2   * House  |
    |______|___**___|________|
    |      |  City  |        |
    |Rubble|  Block |Mystic's|
    |      *    1   * House  |
    |______|________|________|
"""


name = raw_input("Enter your name: ")
print "Welcome to the Atlantis Excavation Zone, %s." % name
print "Your first day on the job and we already have a new cave for you to map... LUCKY!"
print "The DeepBlue team takes you down to the sub base. Time to get to work."
main_menu(location, inventory, items) # **this is line 236**

А вот трассировка:

Traceback (most recent call last):
File "ex36_2.py", line 236, in <module>
main_menu(location, inventory, items)
File "ex36_2.py", line 133, in main_menu
travel = travel(location)
UnboundLocalError: local variable 'travel' referenced before assignment

Я думал, что переменная была назначена в строке 133. Чего мне здесь не хватает?

1 Ответ

10 голосов
/ 03 ноября 2011

Первая строка

travel = travel(location)

неявно помечает имя travel как локальное для всей функции .Во всех поисках этого имени ищется локальное имя, в том числе и в правой части цитируемой строки.В то время нет никакого значения, назначенного локальному имени, хотя, следовательно, ошибка.Может существовать глобальное имя travel, но поскольку компилятор определил travel как локальное имя, он будет смотреть только в локальном пространстве имен.Используйте другое имя для локальной переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...