Python - c的功能

时间:2013-11-13 18:09:12

标签: python dictionary

我正在开发一个自选冒险项目,其主要功能接受3个参数。

  • 第一个参数由函数打印。这始终是包含描述场景的文本的变量
  • 第二个参数始终是一个变量,其中包含与当前场景相关的选项,该选项由函数
  • 打印
  • 第三个参数是一个字典,其键对应于场景选择,并与用户的输入进行比较。键的值包含接下来的3个参数。

实施例。

text1 = 'This is the scenario'  
text2 = 'These are the choices'

dict2 = {'1':[text2, text1, dict1]}
dict1 = {'1':[text1, text2, dict2]}

def mainloop(scenario, choice, consequence):
    print scenario
    print choice

    answer = raw_input('Please input 1, 2 or 3>>> ')

    if answer in consequence.keys():
        mainloop(*consequence[answer])

mainloop(text3, text2, dict1)   

我认为这是设计项目的好方法,但是我遇到了字典参数的问题。因为字典值包含一个参数列表,其中包括其他字典,我不断收到错误:

NameError: name 'dict1' is not defined

翻转我定义字典的顺序预期导致相同的错误,只有' dict2'没有被定义。关于如何让这个概念起作用的任何建议?或者是时候采取完全不同的方法了?

4 个答案:

答案 0 :(得分:3)

我不太确定你为什么需要两个dicts,但假设你这样做,可以用循环引用来定义dicts:

text1 = 'This is the scenario'  
text2 = 'These are the choices'

dict1, dict2 = {}, {}
dict2['1'] = [text2, text1, dict1]
dict1['1'] = [text1, text2, dict2]

答案 1 :(得分:1)

我建议重新考虑一下整体方法。

正如其他人所指出的那样,mainloop()实际上并不是一个循环;这是一个递归函数。理想情况下,如果这是一个游戏循环,你会希望它更像......

def myGameLoop():
    gameRunning = True
    while gameRunning:
        # code that displays your rooms, gets user input,
        #and checks to make sure that gameRunning is not False.
        #for an example, something like:
        if somethingAwfulHappened
            gameRunning = False

通过这种方式,您不必多次调用mainloop,并且没有理由自行调用。

此外,你的房间决定/列表一直告诉你他们不存在的原因是因为,他们没有:)这实际上是一个很好的例子,为什么分离你的顾虑是个好主意! / p>

以这种方式思考:为什么“房间”对象 - 无论是字典,列表,对象等 - 是否需要包含有关其他房间的任何数据?您的厨房可能会通向您的浴室,但您的厨房是否知道它通向浴室?它是通过浴室而不是卧室来达到新的目的吗?就像你的厨房没有“关心”它连接到你的浴室一样,你的dicts也不需要通过在他们自己的数据中明确地相互命名来“知道”它们是连接的。

理想的方法可能是去定义所有房间,然后创建一个描述房间之间关系的“地图”。例如:

kitchen = {
    "name":"Kitchen",
    "description": "This is the kitchen! It's nice and clean.",
    "exits": "S", "E"
}

bathroom = {
    "name":"Bathroom",
    "description":"This is the bathroom. Someone left a towel on the floor.",
    "exits":"W", "S"
}
#and so on, creating rooms

现在创建一个地图字典,它只包含所有这些信息并描述这些退出的工作方式。

mapOfHouse = {
    "kitchen": kitchen,
    "leadsTo": {
        "S": bathroom,
        "E": someOtherRoom ##some other place you've defined
    },
    "bathroom": bathroom,
    "leadsTo": {
        "S": otherAwesomePlaces,
        "E": kitchen
    },

    #and so on for other rooms in the house/on the map/etc
 }

一旦你勾勒出所有这些,然后你设置你的游戏环以获得你的玩家的输入,在房间的出口处检查它,如果有匹配,只要循环仍然是True它就会重新开始到顶部,显示更新的信息。

似乎就像更多的工作,但实际上这给了你很大的自由。它允许您在设计时严格关注房间,然后在更新时严格关注地图,然后让您设计一个游戏循环,它并不关心它循环的内容,只要很长时间因为它始终保持True并得到玩家的良好指示。

答案 2 :(得分:0)

您在dict2中引用了dict1,但dict1还没有存在。

答案 3 :(得分:0)

您的问题如下:

dict2 = {'1':[text2, text1, dict1]} # NameError: Here dict1 does not exist yet
dict1 = {'1':[text1, text2, dict2]}

您只能通过在引用对象之前定义对象来解决此问题。 为了实现这一目标,您可以执行以下操作:

dict1, dict2 = {}, {} # Define both objects
dict1[1] = [text2, text1, dict2] # Here dict2 is already defined, no NameError
dict1[2] = None # ...
dict2[1] = [text1, text2, dict1] # And here is dict1 already defined too
dict2[2] = None # ...

我们可以问的问题是:引用一个对象,然后更改它会改变引用吗? 答案是,确实如此;如果你使用的是引用而不是副本(asigning dictonaries总是引用它们)。

如果您想复制而不是参考,该怎么办?

嗯,您可以通过copy模块中的deepcopycopy函数执行此操作。

NameError的问题在于没有定义名称; Python不使用名称来跟踪变量:相同的名称可以对应不同的变量(在不同的范围内,或在不同的时间),同一个变量可以通过不同的名称访问(通过将一个名称的值分配给另一个)。

当您执行del x时,从其名称中取消变量,但您并不总是消除该对象。

例如,以下代码正常工作并正确打印stash,通过del运算符,我们将str对象'hello'从对象x取消链接包含它。

x = {1: 'hello'}
stash = x[1]
del x[1]

print stash

通过删除stash对象,'hello'对象现在可能在某些时候被垃圾收集。

提醒

如果要通过名称引用其他对象,则必须在引用之前对其进行命名。