[英](Python, Windows) Calling class functions from other classes
我試圖從另一個類的一個類中調用一個函數。 這是我的代碼:
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
,所有行都清除了,而不是顯示“ Player go”。 “錯誤”也不會顯示。
我想要“玩家去”。 在我調用Player().Go()
。 我該怎么做呢? 感謝您的幫助!
發生這種情況的原因是,當您調用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 )。
您面臨的部分問題(也許是它使您感到困惑的原因)是您試圖使用類變量來保存消息,但實際上您沒有在修改它們。 每當您輸入self.variable = something
,即使類變量存在相同名稱,您也將要分配給該實例變量。 這是因為盡管您可以通過self
訪問類變量,但是您不能以這種方式分配它們。
您可以通過將類變量更精確地命名為GameRoom.variable
來避免這種GameRoom.variable
,但是我建議完全避免類變量。 除了常量以外,它們很少有用。 這是您可以使用實例變量設置與現在相同的方法:
class GameRoom(object):
def __init__(self):
self.message1 = ""
self.message2 = ""
# etc...
其余代碼可以相同(它已經在處理實例變量)。
設置使用實例變量后,您將遇到的麻煩是,每當您要訪問類的方法時,都在創建類的新實例。 也就是說,您的GameRoom
會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__
方法的參數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.