【问题标题】:(Python, Windows) Calling class functions from other classes(Python, Windows) 从其他类调用类函数
【发布时间】:2012-12-03 01:45:57
【问题描述】:

我正在尝试从另一个类调用一个类中的函数。这是我的代码:

import os

class GameRoom():

    msgLine1 = ""
    msgLine2 = ""
    msgLine3 = ""
    msgLine4 = ""
    msgLine5 = ""

    def GameStatus(self):
        while True:
            os.system('cls')
            print self.msgLine1
            print self.msgLine2
            print self.msgLine3
            print self.msgLine4
            print self.msgLine5 + "\n"
            print "Do what?\n"
            userDecision = raw_input()
            if userDecision.upper() == "GO":
                Player().Go()
                break
            else:
                self.CycleMessages("That's not a valid choice!")

    def CycleMessages(self,newMsg="error"):
        self.msgLine5 = self.msgLine4
        self.msgLine4 = self.msgLine3
        self.msgLine3 = self.msgLine2
        self.msgLine2 = self.msgLine1
        self.msgLine1 = newMsg

class Player():
    def Go(self):
        GameRoom().CycleMessages("Player goes.")
        GameRoom().GameStatus()

def main():
    GameRoom().GameStatus()

if __name__ == '__main__':
    main()

当我通过自己调用CycleMessages 时,这些行填满了“这不是一个有效的选择!”通常,就像他们应该的那样。当我从 Player 类中调用 CycleMessages 时,所有的行都清除了,而不是显示“玩家开始了。”。 'error' 也不显示。

我想要“玩家去”。当我打电话给Player().Go() 时出现。我该怎么做呢?感谢您的帮助!

【问题讨论】:

    标签: python windows class function variables


    【解决方案1】:

    发生这种情况是因为当您调用GameRoom().CycleMessages("Player goes.") 时,您是在GameRoom 的新实例上调用它。轻松修复:

    class GameRoom():
    
        def GameStatus(self):
            ...
                if userDecision.upper() == "GO":
                    # Pass `Player` this instance of `GameRoom`
                    Player().Go(self)
                    break
                else:
                    self.CycleMessages("That's not a valid choice!")
    
    class Player():
    
        def Go(self, game):
            # And here, call `CycleMessages` on the passed instance of `GameRoom`.
            game.CycleMessages("Player goes.")
            game.GameStatus()
    

    另外,这不是您的问题,但您可能需要考虑更改命名约定(请参阅:PEP8)。

    【讨论】:

    • 我会重命名 GameRoom 参数以避免隐藏类名。另外,为了避免不断加深的递归,我建议从Player.Go 的末尾删除GameStatus() 调用,而只是返回。然后只需从GameStatus 中删除break 行,您将只有一个循环。
    • 谢谢!它现在工作正常。我知道命名约定,但我是一个懒惰的人或类似的人。抱歉这么久才回复!
    【解决方案2】:

    您面临的部分问题(也许是它让您感到困惑的原因)是您尝试使用类变量来保存您的消息,但实际上您并没有修改它们。每当您键入self.variable = something 时,您将分配给一个实例变量,即使存在同名的类变量。这是因为虽然您可以通过 self 访问类变量,但您不能以这种方式分配给它们。

    您可以通过更准确地将类变量命名为GameRoom.variable 来避免这种情况,但我建议完全避免使用类变量。除了常量之外,它们很少有用。以下是如何使用实例变量设置与现在相同的内容:

    class GameRoom(object):
        def __init__(self):
            self.message1 = ""
            self.message2 = ""
            # etc...
    

    其余代码可以相同(它已经在操作实例变量)。

    一旦您开始使用实例变量,您会遇到的麻烦是,您在想要访问类的方法时创建了一个新的类实例。也就是说,您的GameRoom 会一遍又一遍地创建一个新的Player 实例,而Player 类会在每次移动后创建新的GameRoom 实例。这通常不是您想要做的。相反,您可能只想为它们中的每一个创建一个实例,并继续重复使用它们。

    @kuyan 的回答显示了如何避免在 Player.Go 方法中创建新的 GameRoom 实例,但您可能也希望避免创建大量 Player 实例(特别是如果您将有任何复杂的稍后在Player 类中)。

    我愿意:

    def GameStatus(self):
        player = Player()    # create a Player instance in a local variable
    
        # ...
    
        if userDecision.upper() == "GO":
            player.Go(self)  # use the variable!
    

    另一种选择是将播放器创建添加到__init__ 方法(将其分配给self.player 或实例上的其他名称)。然后,您可以从GameRoom 中的任意数量的方法访问相同的Player 实例。或者,如果您希望相同的 Player 实例在不同的房间中可用,您甚至可以将其作为 __init__ 方法的参数。

    【讨论】:

      猜你喜欢
      • 2013-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多