Python 在实例化类对象之前,有没有一种方法可以引用它?

Python 在实例化类对象之前,有没有一种方法可以引用它?,python,python-2.7,Python,Python 2.7,我正在尝试用Python制作一个简单的文本游戏。我有一间房间教室: class Room(): def __init__(self, monster, exits, loot): self.room_guard = monster self.exits = exits self.guard_is_alive = True self.loot = loot 当我创建房间时,我收到一个错误,因为我在创建房间之前调用了它们,如下

我正在尝试用Python制作一个简单的文本游戏。我有一间
房间
教室:

class Room():
    def __init__(self, monster, exits, loot):
        self.room_guard = monster
        self.exits = exits
        self.guard_is_alive = True
        self.loot = loot
当我创建房间时,我收到一个错误,因为我在创建房间之前调用了它们,如下所示:

room_2 = Room(spider, {"West": room_3, "East": room_4, "South": room_1}, 2)
room_1 = Room(trogdor, {"North": room_2}, 2)

房间2不能有
“South”:房间1
,因为它尚未实例化。有办法解决这个问题吗?

两个选项:间接寻址、创建后赋值

不要直接引用房间,而是使用将房间名称映射到房间的
dict

rooms = {}
rooms['room_2'] = Room(spider, {"West": 'room_3', "East": 'room_4', "South": 'room_1'}, 2)
rooms['room_1'] = Room(trogdor, {"North": 'room_2'}, 2)
或在创建房间对象后指定出口:

room_2 = Room(spider, {}, 2)
room_1 = Room(trogdor, {}, 2)

room_2.exits = {"West": room_3, "East": room_4, "South": room_1}
room_1.exits = {"North": room_2}

在创建对象之前,无法引用该对象。但是,您可以在创建对象后修改
退出
词典,以在房间之间创建链接。一个很好的方法是让您创建的第二个房间通过一个附加参数自动创建一些回自身的链接:

class Room():
    def __init__(self, monster, exits, loot, exits_back={}):
        self.room_guard = monster
        self.exits = exits
        self.guard_is_alive = True
        self.loot = loot
        for direction, room in exits_back.items():
            room.exits[direction] = self
然后,您会将一个额外的字典传递给后面房间的构造器,让它将链接从前面房间设置回自身:

room_2 = Room(spider, {"West": room_3, "East": room_4}, 2)        # no room_1 ref here
room_1 = Room(trogdor, {"North": room_2}, 2, {"South": room_2})   # extra dict passed

这个问题有很多解决办法。这是另一个。此解决方案等待初始化对象,直到创建完所有对象

class Room():

    def create(self, monster, exits, loot=None):
        self.room_guard = monster
        self.exits = exits
        self.guard_is_alive = True
        self.loot = loot

room_1 = Room()
room_2 = Room()
room_3 = Room()
room_4 = Room()

room_1.create('spider', {"West": room_3, "East": room_4, "South": room_1}, 2)
room_2.create('trogdor', {"North": room_2}, 2)

编辑:使用上述方法,这里有一种可能的房间组织方式。我已把房间存放在一个仓库里。这个解决方案很好,因为你不必担心出口在哪里;程序会为您计算创建的每个房间的值

rooms = []
horizontal_room_count = 2
vertical_room_count = 2

class Room():

    def __init__(self, x, y):
        self.x = x
        self.y = y

    def create(self, monster, loot):
        self.room_guard = monster
        self.exits = self.get_exits()
        self.guard_is_alive = True
        self.loot = loot

    def get_exits(self):
        x, y = self.x, self.y

        def get_room(x2, y2):
            if x2 < 0 or y2 < 0 or x2 >= horizontal_room_count or y2 >= vertical_room_count:
                return None
            return rooms[x2][y2]


        return {
                    'West': get_room(x-1, y), 
                    'East': get_room(x+1, y),
                    'North': get_room(x, y+1),
                    'South': get_room(x, y-1)
                }

rooms = [[Room(x,y) for x in range(horizontal_room_count)] for y in range(vertical_room_count)]

rooms[0][0].create('spider', loot=2)
rooms[0][1].create('trogdor', loot=2)

我能想象的最好的方法是创建对象,然后分两个不同的步骤创建链接

class Room(object):
    def __init__(self, monster, loot):
        self.exits = {direction:None for direction in
                      ["North", "South", "East", "West"]}
        # rooms have no exits until you add links to them manually
        self.room_guard = monster
        self.guard_is_alive = True
        self.loot = loot
    def add_link(self, other, ordinal):
        """Creates a link between this room and another in the specified direction

        room_A.add_link(room_B, 'East')
        sets room_A.exits['East'] = room_B and room_B.exits['West'] = room_A"""

        if not hasattr(other, 'exits')
            raise ValueError("Can only link with other objects with exits")
        ordinal_map = {"North":"South", "South":"North",
                       "East":"West", "West":"East"}
        try:
            other_ordinal = ordinal_map[ordinal]
        except KeyError:
            raise ValueError("ordinal must be one of {}".format(
                    ', '.join(ordinal_map.keys())))

        self.exits[ordinal] = other
        other.exits[other_ordinal] = self
首先整理房间

map = """  A - B   C
           |       |
           D - E - F """
# bonus points if you can build a function that takes this as input and
# outputs the correct structure of rooms!!!

rooms = {key:Room(*args) for key,args in zip("ABCDEF",monster_loot_tuples)}
# monster_loot_tuples would be a list like [("Gargoyle","+1 Sword of Smiting"), ...]
然后添加链接

rooms['A'].add_link(rooms['B'], 'East')
rooms['A'].add_link(rooms['D'], 'South')
rooms['D'].add_link(rooms['E'], 'East')
rooms['E'].add_link(rooms['F'], 'East')
rooms['F'].add_link(rooms['C'], 'North')

我不知道为什么我没有想到这一点。谢谢有趣。我要试试这个。非常感谢。当然,
房间
可能更好地用作列表,除非您以后需要专门按名称访问它们。
rooms['A'].add_link(rooms['B'], 'East')
rooms['A'].add_link(rooms['D'], 'South')
rooms['D'].add_link(rooms['E'], 'East')
rooms['E'].add_link(rooms['F'], 'East')
rooms['F'].add_link(rooms['C'], 'North')