IndexError:列表索引超出范围/难以使用OOP调用列表

时间:2023-01-16 16:39:11

I'm new to coding and have been teaching myself python through the 'Learn Python the Hard Way' tutorial and am currently making a simple game. So far everything seems to be working, except for the fact that I can't figure out how to properly call a list one of my Classes makes with other Classes.

我是编码的新手,并通过'学习Python艰难的方式'教程自学python,目前正在制作一个简单的游戏。到目前为止,一切似乎都在起作用,除了我无法弄清楚如何正确调用我的类与其他类之一的列表。

class engine(object):
    def __init__(self,world,days,character):
        self.world = world
        self.days = days
        self.character = character

    def letsdoit(self):
        self.world.worldbuilder()

This is the block meant to actually run the game, lines 9 onward are omitted because they aren't relevant.

这是用于实际运行游戏的块,因为它们不相关而省略了第9行。

world.worldbuilder is the function which creates the map on which the game is actually played.

world.worldbuilder是创建实际播放游戏的地图的功能。

class World(self, width, height):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def worldbuilder(self):
        map = []
        for x in xrange(self.width):
            z = []
            for y in xrange(self.height):
                z.append(self.tiletype())
            map.append(z)
        return map

World.tiletype just randomly generates a tile then resets. When I instantiate an object of World and run worldbuilder (except I print map instead of returning it) it all works perfectly fine. However when I refer to map in conjecture with objects other than World which engine runs, I get errors. The most common is:

World.tiletype只是随机生成一个磁贴然后重置。当我实例化World的一个对象并运行worldbuilder时(除了我打印地图而不是返回它)它完全正常。然而,当我在猜想中使用除了World之外的对象来引用map时,我会遇到错误。最常见的是:

IndexError: list out of range

Specifically I get it in response to:

具体来说,我得到它回应:

class player(object):
    def __init__(self, World):
        self.x = randint(1,World.width)
        self.y = randint(1,World.height)
        self.tilestore = map([self.x][self.y])

Even when I set player.tilestore to equal a generic tile, I run into TypeErrors where it says my 'built_in_function_or_method' item has no attribute 'get_item' when I refer to map in other places.

即使我将player.tilestore设置为等于通用磁贴,我也会遇到TypeErrors,当我在其他地方引用map时,我说'built_in_function_or_method'项没有属性'get_item'。

I have tried setting list = self.world.worldbuilder(), then calling list instead of map, but then I run into the exact same problems.

我试过设置list = self.world.worldbuilder(),然后调用list而不是map,但后来我遇到了完全相同的问题。

2 个解决方案

#1


0  

You don't seem to call worldbuilder, so maybe you can call it before using map:

你似乎没有打电话给worldbuilder,所以也许你可以在使用map之前调用它:

class player(object):
    def __init__(self, World):
        self.x = randint(1,World.width)
        self.y = randint(1,World.height)
        map = World.worldbuilder()
        self.tilestore = map[self.x][self.y]

And as mentioned by Brionius, using map is a bad idea (unless you want to use the built-in function). This lead to the misleading error message. Using the same name (World) for a class and an instance is also bad.

正如Brionius所提到的,使用map是一个坏主意(除非你想使用内置函数)。这导致误导性错误消息。对类和实例使用相同的名称(World)也很糟糕。

#2


0  

The IndexError is caused by incorrect list index syntax, and the TypeError is caused by a namespace collision. To fix the IndexError, you should use this syntax:

IndexError是由不正确的列表索引语法引起的,TypeError是由命名空间冲突引起的。要修复IndexError,您应该使用以下语法:

self.tilestore = world_map[self.x][self.y]

The TypeError is caused by a namespace collision. In player.init You are using the variable map without initializing map in the local namespace, so map refers to the global namespace, where it contains a reference to the builtin map function. You need to pass map in as an argument to player.init like this

TypeError是由命名空间冲突引起的。在player.init中您正在使用变量map而不在本地名称空间中初始化map,因此map引用全局名称空间,其中包含对内置映射函数的引用。你需要将map作为参数传递给player.init,就像这样

class player(object):
    def __init__(self, world, map):

or get it from a World instance like this

或者从像这样的World实例中获取它

class player(object):
    def __init__(self, world):
        self.x = randint(1,world.width)
        self.y = randint(1,World.height)
        self.tilestore = world.map([self.x][self.y])

You should also, as I did above, change the argument World to world, to avoid another namespace collision, between the class name World and the instance of the class, called World.

您还应该像上面所做的那样,将类名World更改为world,以避免在类名World和类的实例(称为World)之间发生另一个名称空间冲突。

Another problem that can cause the IndexError is your use of randint. Assuming you're using the random.randint function, for arguments a and b, it generates numbers such that a <= N <= b. Note that this range is inclusive on both sides. That means that sometimes self.x is equal to world.width, and self.y is equal to world.height. Both of those values are out of range due to the way you constructed world.map. Here's the fix:

可能导致IndexError的另一个问题是你使用randint。假设您正在使用random.randint函数,对于参数a和b,它会生成数字,使得<= N <= b。请注意,此范围包括双方。这意味着有时self.x等于world.width,self.y等于world.height。由于构造world.map的方式,这两个值都超出了范围。这是修复:

class player(object):
    def __init__(self, world):
        self.x = randint(1,world.width - 1)
        self.y = randint(1,World.height - 1)
        self.tilestore = world.map([self.x][self.y])

You'll have to make similar changes anywhere you are indexing your worldmaps.

在索引世界地图的任何地方,您都必须进行类似的更改。

#1


0  

You don't seem to call worldbuilder, so maybe you can call it before using map:

你似乎没有打电话给worldbuilder,所以也许你可以在使用map之前调用它:

class player(object):
    def __init__(self, World):
        self.x = randint(1,World.width)
        self.y = randint(1,World.height)
        map = World.worldbuilder()
        self.tilestore = map[self.x][self.y]

And as mentioned by Brionius, using map is a bad idea (unless you want to use the built-in function). This lead to the misleading error message. Using the same name (World) for a class and an instance is also bad.

正如Brionius所提到的,使用map是一个坏主意(除非你想使用内置函数)。这导致误导性错误消息。对类和实例使用相同的名称(World)也很糟糕。

#2


0  

The IndexError is caused by incorrect list index syntax, and the TypeError is caused by a namespace collision. To fix the IndexError, you should use this syntax:

IndexError是由不正确的列表索引语法引起的,TypeError是由命名空间冲突引起的。要修复IndexError,您应该使用以下语法:

self.tilestore = world_map[self.x][self.y]

The TypeError is caused by a namespace collision. In player.init You are using the variable map without initializing map in the local namespace, so map refers to the global namespace, where it contains a reference to the builtin map function. You need to pass map in as an argument to player.init like this

TypeError是由命名空间冲突引起的。在player.init中您正在使用变量map而不在本地名称空间中初始化map,因此map引用全局名称空间,其中包含对内置映射函数的引用。你需要将map作为参数传递给player.init,就像这样

class player(object):
    def __init__(self, world, map):

or get it from a World instance like this

或者从像这样的World实例中获取它

class player(object):
    def __init__(self, world):
        self.x = randint(1,world.width)
        self.y = randint(1,World.height)
        self.tilestore = world.map([self.x][self.y])

You should also, as I did above, change the argument World to world, to avoid another namespace collision, between the class name World and the instance of the class, called World.

您还应该像上面所做的那样,将类名World更改为world,以避免在类名World和类的实例(称为World)之间发生另一个名称空间冲突。

Another problem that can cause the IndexError is your use of randint. Assuming you're using the random.randint function, for arguments a and b, it generates numbers such that a <= N <= b. Note that this range is inclusive on both sides. That means that sometimes self.x is equal to world.width, and self.y is equal to world.height. Both of those values are out of range due to the way you constructed world.map. Here's the fix:

可能导致IndexError的另一个问题是你使用randint。假设您正在使用random.randint函数,对于参数a和b,它会生成数字,使得<= N <= b。请注意,此范围包括双方。这意味着有时self.x等于world.width,self.y等于world.height。由于构造world.map的方式,这两个值都超出了范围。这是修复:

class player(object):
    def __init__(self, world):
        self.x = randint(1,world.width - 1)
        self.y = randint(1,World.height - 1)
        self.tilestore = world.map([self.x][self.y])

You'll have to make similar changes anywhere you are indexing your worldmaps.

在索引世界地图的任何地方,您都必须进行类似的更改。