2011-04-04 54 views
2

我正在编写一个非常简单的猜测动物游戏的地方,玩家可以猜测。我花了很长时间来输入所有的信息,我知道它很啰嗦,可能会用更短的时间完成,但我是一个初学者。事情是,其中一部分不起作用。我要在代码并强调arn't工作领域,并解释发生了什么....它为什么说Global Name没有定义它的时候? Python

def animalmenu(): 
    print() 
    print() 
    print('Welcome to the menu. I am thinking of an animal. Select the option\'s below to try and guess my animal.') 
    print() 
    print('a) No. of Legs') 
    print('b) Type of animal') 
    print('c) Preffered Climate') 
    print('d) Size') 
    print('e) Colour') 
    print('f) Diet') 
    print('g) Habitat') 
    print('h) Can be kept as pet') 
    print('i) Guess the animal') 
    print() 
    AniChoice = input('Choose your option: ') 
    if AniChoice == 'a': 
     choicea() 
    if AniChoice == 'b': 
     choiceb() 
    if AniChoice == 'c': 
     choicec() 
    if AniChoice == 'd': 
     choiced() 
    if AniChoice == 'e': 
     choicee() 
    elif AniChoice == 'f': 
     choicef() 
    elif AniChoice == 'g': 
     choiceg() 
    elif AniChoice == 'h': 
     choiceh() 
    elif AniChoice == 'i': 
     guessing() 

所以这是基本的布局菜单。然后,每个选项有一个子菜单,例如:

def choicea(): 
    print() 
    print('') 
    print() 
    guessleg = input('Guess the number of legs (insects may be listed as \'lots\': ') 
    if leg == guessleg: 
     print('True') 
     print('r = Return to menu, g = guess again.') 

    elif leg != guessleg: 
     print('False') 
     print('r = Return to menu, g = guess again.') 

这些子菜单的做工精细,直到你到达子菜单的F到我...我不知道什么是错。你得到你正试图从其中是这样的代码的另一个区域猜测也将继续更多的动物数据...

def animalchoice(): 
    asdf = ('dog', 'monkey', 'parrot', 'fox', 'mouse', 'lady-bird', 'badger', 'shark', 'whale', 'pigeon') 
    from random import choice 
    animal = choice(asdf) 
    if animal == 'dog': 
     leg = '4' 
     breed = 'mammal' 
     climate = 'any' 
     size = 'dog+' 
     colour = 'depends' 
     diet = 'a' 
     habitat = 'ground' 
     pet = 'yes' 

    if animal == 'monkey': 
     leg = '4' 
     breed = 'mammal' 
     climate = 'hot' 
     size = 'dog+' 
     colour = 'brown' 
     diet = 'c' 
     habitat = 'tree' 
     pet = 'no' 

。当我运行脚本时,它工作正常。我在不同的地方添加了循环等,这很好。但是当我尝试运行菜单中的选项g(def choiceg)时,它会出现各种各样的错误,基本上说全局名称'habitat'(我们试图在特定区域中猜测)不是定义。我用与其他地区相同的方式编码这些地区,但它不会工作......我做错了什么?除了冗长的脚本编写方式外.... 帮助!?!?!我如何防止错误?

+0

无论什么时候遇到像这样长时间的重复编码,你应该退后一步,想想是否有一个更好的方法来做到这一点。在这种情况下: 'mapping = {“a”:choicea,“b”:choiceb,...}; 映射[input()]()' 将工作相同,并避免'if'语句的巨大混乱。我认为你的第二个代码段中的数据可能最好存储在一个单独的文件中,以便代码和数据不会混淆。 – katrielalex 2011-04-04 22:36:27

+1

你*知道这是为了使用数据结构而不是所有这些硬编码的东西,对吧?而用这种方式编写它使得维护和验证变得更加困难,而且就此而言,首先难于写入? – 2011-04-04 22:36:53

回答

4

当你定义这些变量,你将它们设置这些功能内。它们实际上并不是全局变量。你的主要选择是

  1. 它们配置为全局变量,
  2. 创建“状态”对象以绕过(比如设置data['habitat'] = 'tree'并返回从animalchoice功能),
  3. 把函数的类内和存储您的值作为类变量,如:

class GuessingGame(object): [...] def animalchoice(self): asdf = ('dog', 'monkey', 'parrot', 'fox', 'mouse', 'lady-bird', 'badger', 'shark', 'whale', 'pigeon') from random import choice animal = choice(asdf) if animal == 'dog': self.leg = '4' self.breed = 'mammal' self.climate = 'any' self.size = 'dog+'

我不能告诉你哪一个是“最好的” BEC这取决于你想如何构建你的程序的其余部分。

0

在那里,犯了这个错误:-) 在使用它的每个函数的开头定义你的全局变量(例如。habitat)和'global'。

快速谷歌想出了下面的文章:

http://effbot.org/pyfaq/how-do-you-set-a-global-variable-in-a-function.htm

而且查找“全球化”在Python文档的完整解释/描述。

(顺便说一句,我认为制表有点坏了,当你复制你的代码#1)

+0

但全局变量只是这样做的,它根据动物的选择随机变化,所以我不知道如何在每个事物没有输入的情况下插入它......如果动物=='狗':等等,为30不同的动物会非常繁琐和冗长,并在每个子菜单之前...你会如何建议这样做?对不起,这是啰嗦 – pythonnoobface 2011-04-04 22:07:31

+1

正如柯克所说,在一个没有局部全局定义的函数中使用变量只是简单地创建一个新的局部变量来“掩盖”你想要使用的全局变量。 – winwaed 2011-04-05 00:37:39

2

除了其他的答案,你可以调整你的代码是这样的:

from random import choice 

data = { 
    "dog": dict(
     leg = '4', 
     breed = 'mammal', 
     climate = 'any', 
     size = 'dog+', 
     colour = 'depends', 
     diet = 'a', 
     habitat = 'ground', 
     pet = 'yes', 
    ), 

    "monkey": dict(
     leg = '4', 
     breed = 'mammal', 
     climate = 'hot', 
     size = 'dog+', 
     colour = 'brown', 
     diet = 'c', 
     habitat = 'tree', 
     pet = 'no', 
    ), 
    # <<Add animals here>> .... 
} 

data["animal"] = data[choice(data.keys())] # Current random animal 

def animalmenu(): 
    choices = { 
     "a": ("No. of Legs", "leg"), 
     "b": ("Type of animal", "breed"), 
     "c": ("Preffered Climate", "climate"), 
     "d": ("Size", "size"), 
     "e": ("Colour", "colour"), 
     # <<add attributes here>>... 
    } 

    while True: 
     for k, v in choices.items(): 
      print "%s) %s" % (k, v[0]) 

     option = raw_input('Choose your option: ') 
     if not option: 
      break 

     if option in choices: 
      guess_attr(choices[option][0], choices[option][1]) 

     print 


def guess_attr(caption, attr): 
    global data 

    while True: 
     guess = str(raw_input('Guess the %s :' % caption)) 
     ok = guess==str(data["animal"][attr]) 
     print ok 
     if ok: 
      break 

     option = raw_input('r = Return to menu, g = guess again: ') 
     if option=="r": 
      break 

    print 


animalmenu() 

这样,您就可以添加动物,而不必修改所有的代码很容易属性。

+0

+1:这是一个更好,更可维护的方法。想要一个数据库后端?用来自SQL查询的结果填充'data'。 – 2011-04-05 03:44:05

1

全局变量是一个适用于整个程序的变量。在你的例子中,你说栖息地不起作用,返回错误全局变量未初始化。这意味着你可能在其他函数中声明了栖息地,也许是选择项,但是由于你在选择中定义了它,只有选择项可以访问它。换句话说,它不是全球性的。如果你希望它是全球性的,你应该在任何函数之外声明它,并且为了安全起见,也不要在循环中声明它。有时奇怪的事情发生在变量。这是每个人在编程时都会犯的一个错误。

此外,而不是列出所有在您的程序中,我可以建议使用它们的单独文件?或者一个数据库来保存这些值?这样,您不必每次修改代码就可以更改值的开始......只是一个友好的建议。

相关问题