搜索dict清单中的项目时的KeyError

时间:2017-08-17 17:19:29

标签: python class dictionary

在过去的几个月里,我一直在尝试创建一个基于文本的Zork风格的游戏作为自学Python的项目。

感谢stackoverflow上的精彩人物以及大量的YouTube视频,我取得了不错的进展。我目前正在处理的问题是在Bag类的代码底部。 正如您将在我的包类中看到的,我有一个名为Take的方法。这个方法最初不在bag类中,它在底部的部分中读取用户命令。

class Bag:

    def __init__(self, inventory):
        self.inventory = inventory

    def addToInventory(self, item):
        for key in list(Location.room.roominv.keys()):
            self.inventory.append(Location.room.roominv[key])
            del Location.room.roominv[key]

    def SearchRoom(self):
        if Location.room.roominv:
            for item in list(Location.room.roominv.keys()):
                print("you find a", item)
        else:
            print("You don't find anything")

    def NoneHere(self, command):
        print("You can't find a", command)

    def Take(self, command):
        for key in list(Location.room.roominv.keys()):
            if Location.room.roominv[key].name == command.split()[1]:
                bag.addToInventory(key)
                print('you take the', key)

    def CheckTake(self):
        if Location.room.roominv and command.split()[1] in Location.room.roominv:
            self.Take(command)
        else:
            self.NoneHere(command.split()[1])

    def CheckInv(self):
        for item in list(bag.inventory):
            print("Your bag contains:", item.name)


player = Player("Jeff", 100)
bag = Bag([])
Location = Location('introd')

command = '  '
while command != "":
    command = input('>>> ')
    if command in Location.room.exits:
        Location.travel(command)
    elif command == 'look':
        Location.RoomDesc()
    elif command == '':
        print('You have to say what it is you want to do!')
        command = '#'
    elif command == 'search':
        bag.SearchRoom()
    elif command.split()[0] == 'Take':
        bag.CheckTake()
    elif command == 'Inventory':
        bag.CheckInv()
    else:
        print('Invalid command')

我被建议将用户命令的逻辑与游戏的其余部分分开,因此我将其移动到指定的类。

然而,在我这样做之前,游戏只能从房间库存中挑选特定物品。现在它拿起了所有。

(定义每个房间的代码将在底部发布,我一直在从单独的.py文件中导入)

目前,我的一个房间只包含多个项目。 “内部小屋”房间,包含“Ornate_Key”和“Knife”。

这是奇怪的事情。如果我尝试使用Ornate_Key,它会很好地拾取它(尽管也会拿起刀)。

但是如果我尝试拿刀,我会收到这个追溯错误

Traceback (most recent call last):
  File "C:/Users/Daniel/Python 3.6/Scripts/PythonPR/Flubbo'sModuleTest.py", line 156, in <module>
    bag.CheckTake()
  File "C:/Users/Daniel/Python 3.6/Scripts/PythonPR/Flubbo'sModuleTest.py", line 130, in CheckTake
    self.Take(command)
  File "C:/Users/Daniel/Python 3.6/Scripts/PythonPR/Flubbo'sModuleTest.py", line 122, in Take
    if Location.room.roominv[key].name == command.split()[1]:
KeyError: 'Ornate_Key'

我花了大约6个小时来修改这些代码,回到旧版本并将当前版本与我没有遇到此问题的版本进行比较,我无法弄清楚为什么会突然发生这种情况。

我对编码很新,所以我对架构/事物的基本原理非常模糊。有谁知道导致这个问题的原因是什么?

在本页的最底部,我将发布一段没有遇到此问题的旧版本的代码。

考虑到这篇文章已经很长了,我不妨发布一个示例游戏,以准确展示正在发生的事情。

    >>> look
You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
{'Search the ground', 'Go North'}
>>> search
you find a Sword
>>> Take Sword
you take the Sword
>>> n
moving to clearing
You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
{'Go East', 'Take flower', 'Go south'}
>>> e
moving to forest path
You begin walking down a well beaten path. The sounds of the forest surround you. Ahead you can see a fork in the road branching to the South and East.You can smell smoke coming from the South, and can hear a stream to the East
{'Go East', 'Go West', 'Go South'}
>>> e
moving to stream
You come upon a relaxing stream at the edge of the woods. It looks like there is something shiny in the water. To your South is a rickety looking shack, to your West is the forest path you came down
{'Go West', 'Go South'}
>>> Take Rusty_Key
you take the Rusty_Key
>>> s
moving to shack
In front of you is a shack, possibly used as an outpost for hunting. It looks dilapidated.
{'Go North', 'Go South'}
>>> s
moving to inside shack
The inside of the shack is dirty. Bits of ragged fur are scattered about the floor and on a table against the back wall.A sharp looking knife is on the table. There is an ornate key hanging on the wall by a string.
{'Take Key', 'Take Knife', 'Go North'}
>>> search
you find a Knife
you find a Ornate_Key
>>> Take Ornate_Key
you take the Ornate_Key
>>> Inventory
Your bag contains: Sword
Your bag contains: Rusty_Key
Your bag contains: Knife
Your bag contains: Ornate_Key
>>> 

1 个答案:

答案 0 :(得分:2)

Take中有Bag方法的任何特定原因?这似乎完全是多余的,考虑到你要做的就是添加该项,如果它存在于字典中。试试这个:

def CheckTake(self):
    key = command.split()[1]
    if Location.room.roominv and key in Location.room.roominv:
        bag.addToInventory(key)
        print('you take the', key)
    else:
        self.NoneHere(key)

此外,您的代码不一致。在某些地方,您可以直接访问全局变量,而在其他地方,您可以冗余地将其传递给函数。我强烈建议你把这个带到Code Review,一旦你开始工作,就把你的行为放在一起。