“UnboundLocalError:赋值前引用的局部变量”错误与函数中定义的变量不一致

2024-09-29 23:17:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在用Python制作一个简单的文本RPG,偶尔也会出错,但不是每次都会。你知道吗

有时,当我通过序列,以获得战斗,它会给我以下错误:

UnboundLocalError: local variable referenced before assignment

或者

enemy name not defined

错误总是源于fightScreen()函数中的第101行:

enemy["level"] = player["level"]

我已经在google上搜索了Stack Overflow,发现函数试图重新定义变量而不是使用以前的变量是有问题的,但在我的例子中,变量(dictionary)是在函数本身内部定义的。你知道吗

我不明白是什么导致了它,尤其是为什么它只会偶尔发生

最简单的例子(我认为这个块可能与问题有关):

player = {
  "name" : "player",
  "level" : 1,
  "ATK" : 5,
  "DEF" : 5,
  "CurHP" : 10,
  "MaxHP" : 10,
  "CurINV" : 0,
  "MaxINV" : 20
}

def randomEnemy():
  monsters = ['Goblin','Slime']
  random_enemy = random.choice(monsters)
  return random_enemy

def fightScreen():
  if randomEnemy() == "Goblin":
    enemy = { #GOBLIN
      "name" : "Goblin",
      "level" : 1,
      "ATK" : 2,
      "DEF" : 2,
      "CurHP" : 5,
      "MaxHP" : 5
    }
  elif randomEnemy() == "Slime":  
    enemy = { #SLIME
      "name" : "Slime",
      "level" : 1,
      "ATK" : 1,
      "DEF" : 3,
      "CurHP" : 5,
      "MaxHP" : 5
    }
  enemy["level"] = player["level"]
  enemy["ATK"] = (enemy["level"] * enemy["ATK"])
  enemy["DEF"] = (enemy["level"] * enemy["DEF"])
  enemy["MaxHP"] = (enemy["level"] * enemy["MaxHP"])
  enemy["CurHP"] = enemy["MaxHP"]
  playerStatus()

这是完整的代码

import re
import random
import os

#player values
player = {
  "name" : "player",
  "level" : 1,
  "ATK" : 5,
  "DEF" : 5,
  "CurHP" : 10,
  "MaxHP" : 10,
  "CurINV" : 0,
  "MaxINV" : 20
}

#predefined variables
loop_i = 1
answer_yes = {'yes', 'y'}
answer_no = {'no', 'n'}
go_world = {'world', 'w'}
go_home = {'home', 'h'}
go_church = {'church', 'c'}
go_blacksmith = {'blacksmith', 'b'}
go_return = {'return', 'run', 'r'}
go_fight = {'fight', 'f'}

#defined functions for input
#ask a question and filter answer from non-letters and spaces
def questionAsked(question):
  inputRaw = input(question + ':')
  inputFiltered = re.sub('[^a-zA-Z0-9]+', '', inputRaw)
  return inputFiltered

def cls():
  #os.system('cls' if os.name=='nt' else 'clear')
  print('\n' * 30)

def playerStatus():
  print ("ATK ",player["ATK"]," | DEF ",player["DEF"]," | HP ",player["CurHP"],"/",player["MaxHP"]," | INV ",player["CurINV"],"/",player["MaxINV"]," | LV",player["level"],sep='')

def randomEnemy():
  monsters = ['Goblin','Slime']
  random_enemy = random.choice(monsters)
  return random_enemy

# screens-------------------------
#enemy prints
def printGoblin():
  print ("--------------------[FIGHT]-------------------")
  print ("|                .                            |")
  print ("|               |                  | .        |")
  print ("|              |                  |//         |")
  print ("|             |  \       /       /  /         |")
  print ("|             |___\     /____  /   /          |")
  print ("|            | \°_\     /°__/ /   /           |")
  print ("|            '               |  /             |")
  print ("|             |   (° °)       -               |")
  print ("|              | _________    |               |")
  print ("|               ||ˇˇˇˇˇˇˇ|   .|               |")
  print ("|               | -------   |                 |")
  print ("|                |_________|                  |")
  print ("|_____________________________________________|")

def printSlime():
  print ("--------------------[FIGHT]-------------------")
  print ("|                       ______                |")
  print ("|                ______/      \_              |")
  print ("|              _/               \             |")
  print ("|             /    \     /       \_           |")
  print ("|            /    0       0        \          |")
  print ("|           /                       \         |")
  print ("|           /        ____            |        |")
  print ("|          /                         |        |")
  print ("|          /                          \       |")
  print ("|         /____________________________\      |")
  print ("|                                             |")
  print ("|                                             |")
  print ("|_____________________________________________|")

# fighting -----------------------
def fightScreen():
  if randomEnemy() == "Goblin":
    enemy = { #GOBLIN
      "name" : "Goblin",
      "level" : 1,
      "ATK" : 2,
      "DEF" : 2,
      "CurHP" : 5,
      "MaxHP" : 5
    }
  elif randomEnemy() == "Slime":  
    enemy = { #SLIME
      "name" : "Slime",
      "level" : 1,
      "ATK" : 1,
      "DEF" : 3,
      "CurHP" : 5,
      "MaxHP" : 5
    }
  enemy["level"] = player["level"]
  enemy["ATK"] = (enemy["level"] * enemy["ATK"])
  enemy["DEF"] = (enemy["level"] * enemy["DEF"])
  enemy["MaxHP"] = (enemy["level"] * enemy["MaxHP"])
  enemy["CurHP"] = enemy["MaxHP"]
  playerStatus()
  if enemy['name'] == "Goblin": #If enemy is GOBLIN
    printGoblin()
    print ("[",enemy["name"], ", LV", enemy["level"]," | HP ",enemy["CurHP"], "/",enemy["MaxHP"],"] ", "Fight (f) | Run (r)", sep='')
    print ("-----------------------------------------------")
    while enemy["CurHP"] > 0:
      userInput = questionAsked("What will you do?").lower()
      if userInput in go_fight:
        cls()
        printGoblin()
        print("You dealt ", (player["ATK"] - enemy["DEF"]) ," damage", sep='')
        enemy["CurHP"] = enemy["CurHP"] - (player["ATK"] - enemy["DEF"])
        if enemy["CurHP"] <= 0:
          print ("You won!")
          input("Press ENTER to go back")
          cls()
          Main()
        else:
          input("Press ENTER to continue")
          cls()
          printGoblin()
          print ("[",enemy["name"], ", LV", enemy["level"]," | HP ",enemy["CurHP"], "/",enemy["MaxHP"],"] ", "Fight (f) | Run (r)", sep='')
          print ("-----------------------------------------------")
      elif userInput in go_return:
        cls()
        Main()
        break

  elif enemy['name'] == "Slime": #If enemy is SLIME
    printSlime()
    print ("[",enemy["name"], ", LV", enemy["level"]," | HP ",enemy["CurHP"], "/",enemy["MaxHP"],"] ", "Fight (f) | Run (r)", sep='')
    print ("-----------------------------------------------")
    while enemy["CurHP"] > 0:
      userInput = questionAsked("What will you do?").lower()
      if userInput in go_fight:
        cls()
        printSlime()
        print("You dealt ", (player["ATK"] - enemy["DEF"]) ," damage", sep='')
        enemy["CurHP"] = enemy["CurHP"] - (player["ATK"] - enemy["DEF"])
        if enemy["CurHP"] <= 0:
          print ("You won!")
          input("Press ENTER to go back")
          cls()
          Main()
        else:
          input("Press ENTER to continue")
          cls()
          printSlime()
          print ("[",enemy["name"], ", LV", enemy["level"]," | HP ",enemy["CurHP"], "/",enemy["MaxHP"],"] ", "Fight (f) | Run (r)", sep='')
          print ("-----------------------------------------------")
      elif userInput in go_return:
        cls()
        Main()
        break

def forestScreen():
  playerStatus()
  print ("--------------------[Forest]-------------------")
  print ("|  *      *      **  |  |  * **   **    **    |")
  print ("| * *      *    **   |  |**    **   *    **   |")
  print ("|  *     ***   *    |  |*        *   *     ** |")
  print ("|   *    __________________________  *     ** |")
  print ("|    |  §                          §      *   |")
  print ("|    |_ §   You've encountered a   §      *   |")
  print ("|       §         Monster!         §      **  |")
  print ("|       § Fight(f)        Run(r)   §        * |")
  print ("|       §__________________________§          |")
  print ("| **       *   *    |  |    **                |")
  print ("|   **      | |    |  |   **  ***  ***      **|")
  print ("|     *     |_|   |  |   *      **    *    *  |")
  print ("|_____________________________________________|")
  print ("Fight (f) | Run (r)")
  print ("-----------------------------------------------")
  userInput = questionAsked("What will you do?").lower()
  if userInput in go_fight:
    cls()
    fightScreen()
  elif userInput in go_return: 
    print ('coward')
    cls()
    Main()

def townScreen():
  playerStatus()
  print ("--------------------[Town]---------------------")
  print ("|       +                       **       |*   |")
  print ("|      / \ Church         Home           |    |")
  print ("|     /   \          /////////\           | **|")
  print ("|    /     \    * *  |_____||_|           | * |")
  print ("| l==|°   °|         *             World _|___|")
  print ("| |__|_||__|          *               => _____|")
  print ("|                                         |   |")
  print ("|                           ##             |  |")
  print ("|           Blacksmith    ###               | |")
  print ("|   * *    //////////\  __#                 | |")
  print ("|   *      |         |__||        *         | |")
  print ("|          |_||______|___|         **      | *|")
  print ("|__________________________________________|__|")
  print ("  Info: Player(p) | Stats (s) | Inventory (i)")
  print ("-----------------------------------------------")
  userInput = questionAsked("Where do you want to go?").lower()
  return userInput

# Main executor, menu ------------------
def Main():
  while loop_i > 0:
    if townScreen() in go_world:
      print('Going to world...')
      cls()
      forestScreen()
      break
    elif townScreen() in go_home:
      print('Going home...')
    elif townScreen() in go_church:
      print('Going to church...')
    elif townScreen() in go_blacksmith:
      print('Going to blacksmith...')  
    else:
      print('What?')

# Sequence start-----------------------------------------------------  
while loop_i > 0:
  userInput = questionAsked("Start (Y/N)?").lower()
  if userInput in answer_yes:
    print ("Okay, let's do it")
    break;
  elif userInput in answer_no:
    print ("That's too bad")
    break;
  else:
    print ('What?')
  print("So your answer is " + userInput + ".")
cls()
Main()

Tags: nameingoifdeflevelclsplayer
1条回答
网友
1楼 · 发布于 2024-09-29 23:17:54

我们只需要看以下几行:

def fightScreen():
  if randomEnemy() == "Goblin":
    enemy = …
  elif randomEnemy() == "Slime":  
    enemy = …
  enemy["level"] = player["level"]

简单的问题:如果randomEnemy()返回的不是“Goblin”或“Slime”,会发生什么?在这种情况下,没有定义enemy。你知道吗

或者,因为这不可能发生,在第一个调用中返回"Slime",但是在第二个调用中返回"Goblin"?然后你有enemy未定义,你的错误就发生了。你知道吗

简单解决方案:

def fightScreen():
  enemyName = randomEnemy()
  if enemyName == "Goblin":
    enemy = …
  elif enemyName == "Slime":  
    enemy = …

或者,只要这些是唯一的选择:

def fightScreen():
  if randomEnemy() == "Goblin":
    enemy = …
  else:
    enemy = …

但我会提出一个完全不同的概念:让你的敌人类型是阶级。你知道吗

然后你就有了

…
class Goblin(object):
    def __init__(self):
        self.name = "Goblin"
        self.level = 1
        self.ATK = 2
        self.DEF = 2
        self.curHP = 5
        self.maxHP = 5

    def print(self):
      print ("          [FIGHT]         -")
      print ("|                .                            |")
      print ("|               |                  | .        |")
      print ("|              |                  |//         |")
      print ("|             |  \       /       /  /         |")
      print ("|             |___\     /____  /   /          |")
      print ("|            | \°_\     /°__/ /   /           |")
      print ("|            '               |  /             |")
      print ("|             |   (° °)       -               |")
      print ("|              | _________    |               |")
      print ("|               ||ˇˇˇˇˇˇˇ|   .|               |")
      print ("|               |    -   |                 |")
      print ("|                |_________|                  |")
      print ("|_____________________________________________|")

        …

class Slime(object):
    def __init__(self)
        self.name = "Slime"
        self.level = 1
        self.ATK = 1
        self.DEF = 3
        self.curHP = 5
        self.maxHP = 5
    def print(self):
      print ("          [FIGHT]         -")
      print ("|                       ______                |")
      print ("|                ______/      \_              |")
      print ("|              _/               \             |")
      print ("|             /    \     /       \_           |")
      print ("|            /    0       0        \          |")
      print ("|           /                       \         |")
      print ("|           /        ____            |        |")
      print ("|          /                         |        |")
      print ("|          /                          \       |")
      print ("|         /____________________________\      |")
      print ("|                                             |")
      print ("|                                             |")
      print ("|_____________________________________________|")


def randomEnemy():
  monsters = [Goblin, Slime]
  random_enemy = random.choice(monsters)
  return random_enemy() # instantiate the enemy here

# fighting            -
def fightScreen():
  enemy = randomEnemy()
  …

这个要优雅得多。你知道吗

相关问题 更多 >

    热门问题