Python:类“init”中的 if-else;这有用吗?

5 python if-statement class

我是另一个正在经历“艰难学习Python”的编程新手,并且遇到了一些我不完全理解的事情。

我首先要说的是,虽然我真的很喜欢他的课程计划,但一个不幸的副作用似乎是我不明白编程世界中涉及的很多技术演讲。我花了两天时间才弄清楚什么是“实例化”,到现在我也只是觉得我明白了,呵呵。因此,希望我的查询的答案尚未以更具技术描述性的方式提出,如果有的话,我很抱歉是多余的。

不管怎样,我在这里想做的是完成一次文本冒险,使用类来描述每个房间。我实际上正在做的是将我的旧作品导入到这种更新的、更“OOP”的做事方式中——转换一个本质上有 980 行函数调用的程序。

因此,之前我在每个功能中都有这些“房间”,它们会检查您是否达到了某些游戏目标,以便向您描述房间。例子:

def room_one():
    if "flashlight" in pack:
        print "You see an exit to the NORTH and a bear to the EAST."
    elif "flashlight" not in pack:
        print "It's too dark to see."
Run Code Online (Sandbox Code Playgroud)

无聊的房间,但描述恰当。因此,在尝试使用类来做到这一点时,我似乎遇到了困难。我将向您展示我用来定义游戏“跑步者”和房间类的代码。

class Runner(object):
    def __init___(self):
        self.goals = [] #an array for game achievements (talked_to_king, etc)
        self.pack = [] #an array for game items (flask, key, etc)

    def play(self, currentroom, gamestate):

        while True:

            print "\n--------"
            print currentroom.desc #this line prints the room description, could
            cmd = raw_input("> ")  #it also be part of the problem?
            gamestate.state = currentroom.actions(cmd)

            if gamestate.state != "SAME":
                currentroom = gamestate.state

            else:
                pass

class Room(object):
    def __init__(self):
        self.desc = "null" #short room description
        self.lookdesc = "super null" #longer room description for the LOOK command


    def actions(self, cmd):
        if 'help' in cmd:
            print """
            'look' -- see your surroundings, including exits.
            'get' -- to pick up an item (if it can be picked up).
            'inventory' -- displays your collected items
            'throw' -- some objects can be thrown
            'talk' -- speak to someone
            Other commands, or objects to interact with, will tend to
            show up IN UPPERCASE. (but still type them in lowercase!)
            Cardinal directions (north, south, east, west) for movement.
            """
            return "SAME"
        elif 'inv' in cmd:
            print "--Inventory--\n"
            for items in game.pack:
                print items
            print "-------------\n"
            return "SAME"
        elif 'look' in cmd:
            print self.lookdesc
            return "SAME"
        elif 'goals' in cmd:
            for goal in game.goals:
                print goal
            return "SAME"
        else:
            print "That won't work here."
            return "SAME"


class Office(Room):

    def __init__(self):

        super(Office, self).__init__()
        # here's the part that doesn't work
        if 'principal' in game.goals:
            self.desc = "You're in the principal's office, and there's a zombie in here!"
        else:
            self.desc = "You're in the principal's office."

        self.lookdesc = "The walls in here are dingy from decades of smoking.\nA door to the WEST leads back to the foyer."



    def actions(self, cmd):

        if "west" in cmd and not "principal" in game.goals:

            print "Buck up and talk to the old prune."

            return "SAME"

        elif "talk" in cmd:

            print "You call to the principal."
            game.goals.append('principal')
            next = raw_input("--Mr. Friiiiinkseseeees...--")
            print "But OH MY DAMN he's actually a zombie now."
            next = raw_input("--Aww weak--")
            return "SAME"

        return super(Office, self).actions(cmd)
Run Code Online (Sandbox Code Playgroud)

为了检查以确保附加了“goals”数组,我在 Room 父类中放置了一个简单的目标检查函数,并且果然 game.goals 被附加了。但我的 if-else 语句似乎实际上没有做任何事情;无论目标数组中有什么,当我回到房间时,我总是会得到其他的描述。

公平地说,像那样将 if-else 放在 room init 中有点像在黑暗中射击,事实上,我很惊讶我没有收到一条错误消息告诉我那不是那些东西所在的地方!但事实上,它似乎并不关心 game.goals 数组的内容,这告诉我这不是最好的方法。我应该如何实施这个?

作为一个子问题 - 对于这样的程序,如果游戏状态变化足够大,以至于房间的内容发生了巨大的改变,那么为改变的房间设置一个完整的其他类是否会被认为更好?维护“地图”并说 RoomThree(Room) 始终是 RoomThree 是否更重要,无论游戏状态发生什么变化,或者当游戏返回到 RoomThree 时,该地方已被毁坏、被抢劫、着火,充满了吸血鬼和生菜的味道,这应该是一个完全不同的 RoomThree 吗?我有点希望不会,因为让每个房间“成为那个房间”并让 game.goals 和 game.pack 之类的内容更改类的实例而不是仅仅为它创建一个新类似乎更合理当满足某些条件时。

无论如何,这很冗长。tl;dr - 我这样做很奇怪吗?

再次编辑:清理了主要问题的代码以满足此处人们建议的新代码,还添加了父类“Room”以查看这是否不是问题的一部分。仍然没有解决方案,但我确实相信代码的质量已经提高了:) whee

最终编辑(我希望):啊哈,斯通的回答又是最有帮助的。由于我向跑步者返回“相同”,因此它使用的是旧的 Office 实例。我需要创建一个全新的实例以使其识别更改;通过返回“Office()”而不是“SAME”我完成了这一点。感谢大家的帮助,不仅解决了手头的问题,而且使代码更易于阅读,并帮助我改变了我对冗长的 if-else 语句的想法。哇:D

Dav*_*one 1

当你有 100 个房间时会发生什么?你的 play 函数有 100 个 if 语句,只是为了设置你所在的房间吗?(基本上再设置一下)

当游戏状态发生变化时,直接将其设置为您想要的任何状态可能会更好。

编辑:我刚刚重新阅读了您的内容,现在问题似乎很明显,除非您遗漏了重要的代码。

您唯一一次向目标添加主体是在 Office 类的成员函数内部。因此,当您开始向目标添加主体时,为时已晚,Office 已经初始化,并且不会重新初始化,除非您创建一个新的 Office 实例。添加该目标后,您需要更新房间的描述。