“self”作为方法属性

时间:2014-06-08 09:44:23

标签: python properties attributes self

我正在尝试自学Python,我正在努力通过一个python程序,这本质上是一个pacman游戏。在这样做的同时,我发现了以下类调用,其中包含'self'作为方法属性。

game = Game(agents, display, self, catchExceptions=catchExceptions)

背景:

此方法调用是以下函数的一部分:

class ClassicGameRules:
    """
    These game rules manage the control flow of a game, deciding when
    and how the game starts and ends.
    """
    def __init__(self, timeout=30):
        self.timeout = timeout

    def newGame( self, layout, pacmanAgent, ghostAgents, display, quiet = False, catchExceptions=False):
    [1] agents = [pacmanAgent] + ghostAgents[:layout.getNumGhosts()] 
    [2] initState = GameState() 
    [3] initState.initialize( layout, len(ghostAgents) ) 
    [4] game = Game(agents, display, self, catchExceptions=catchExceptions) 
    [5] game.state = initState 
    [6] self.initialState = initState.deepCopy()

[1]为了使这个更加可口,“代理人”将pacman和ghost代理对象组合成一个列表列表,打印时看起来像这样:

[<keyboardAgents.KeyboardAgent instance at 0x1004fe758>, <ghostAgents.RandomGhost instance at 0x1004fe518>, <ghostAgents.RandomGhost instance at 0x1004fe7a0>, <ghostAgents.RandomGhost instance at 0x1004fe950>, <ghostAgents.RandomGhost instance at 0x1004feb90>]

[2] initState = GameState():GameState()是一个包含有关游戏状态的各种信息的数据对象

[3] initState.initialize(layout,len(ghostAgents)):从布局数组初始化第一个游戏状态。这个布局数组让程序知道pacman和ghost产生的位置,食物和胶囊的显示位置以及可以找到墙壁的位置。

[4] game = Game(agent,display,self,catchExceptions = catchExceptions):Game类管理控制流,征求代理的动作。代理可以是键盘代理(由控制pacman的播放器控制)和控制重影的自动代理(参见[1])。

[5] game.state = initState:将[2]的内容复制到变量game.state中。

[6] self.initialState = initState.deepCopy():deepCopy是一个函数,它对定义游戏板游戏状态的变量运行复制操作,例如布局或食物的位置。

CLASS GAME: 以下是Game类的代码:

class Game:
"""
The Game manages the control flow, soliciting actions from agents. 
"""

def __init__( self, agents, display, rules, startingIndex=0, muteAgents=False, catchExceptions=False ):
    self.agentCrashed = False
    self.agents = agents                                           ## agents contain the pacman and ghost agent objects combigned into a list of lists agents = [pacmanAgent] + ghostAgents[:layout.getNumGhosts()]
    self.display = display                                        
    #print("This is the display object" + str(self.display))
    self.rules = rules                                             ## The rules are passed on as the self attribute of the ClassicGameRules class within the call of Game in newGame [REF 115].
    self.startingIndex = startingIndex                             ## starting index is given as default attribute by the __init__ method.
    self.gameOver = False
    self.muteAgents = muteAgents
    self.catchExceptions = catchExceptions
    self.moveHistory = []
    self.totalAgentTimes = [0 for agent in agents]                 ## This creates a list that replaces the list elements of the agents list, which contains the agent objects, with zeros. It looks something like this [0,0,0]
    ##print(self.totalAgentTimes)
    self.totalAgentTimeWarnings = [0 for agent in agents]          
    self.agentTimeout = False
    import cStringIO                                              
    self.agentOutput = [cStringIO.StringIO() for agent in agents] 

什么让我感到困惑

当调用game = Game(agent,display,self,catchExceptions = catchExceptions)时,“self”作为属性传递给Game。在Game中,“self”中包含的数据被置于“规则”中变量。

但这个变量是否包含?

直觉上我会建议它是newGame对象的“self”实例。但是看看这个方法如何被称为self.initialState = initState.deepCopy(),这似乎没有意义......

或者我们是否引用了ClassicGameRules类的自我对象?

我知道这是一些要阅读的文字,但我不太清楚如何缩短这个问题。如果需要更多信息,请告诉我。任何帮助将受到高度赞赏。 :)

Z_101

2 个答案:

答案 0 :(得分:1)

在班级newGame的方法ClassicGameRules中,self代表班级的当前实例:

game = Game(       agents, display, self, ...) 
                      v       v       v
def __init__(self, agents, display, rules, ...)

此处self方法的第一个__init__代表将在Game类中创建的新对象。

在您的情况下,Game类在rules中有ClassicGameRules实例的引用,该实例调用了Game实例的构造函数。后面的deepCopy无关,只是通过将刚刚创建的对象(game)的状态复制到“父”对象({{的实例)来同步两个对象的初始状态。 1}})。

答案 1 :(得分:1)

该行:

game = Game(agents, display, self, catchExceptions=catchExceptions) 

ClassicGameRules.newGame中调用Game.__init__,其中包含三个位置参数和一个关键字参数,以及新Game实例的隐式第一个位置参数。 Game.__init__定义为:

def __init__(self, agents, display, rules, startingIndex=0, muteAgents=False, catchExceptions=False ): 
                 # agents  display  self   [default]        [default]         catchExceptions

至关重要的是,调用函数中的self 与被调用函数中的self相同。此调用将ClassicGameRules实例作为参数rules传递给Game实例。这会创建一个双向链接:

  • 您可以通过Game访问ClassicGameRules实例方法中的self.game个实例;和
  • 您可以通过ClassicGameRules访问Game实例方法中的self.rules个实例。

下一部分:

game.state = initState 
self.initialState = initState.deepCopy()

state个实例的Game属性设置为initState,然后将该状态的副本保存到self.initialState(其中{ {1}}引用self实例,因为我们在ClassicGameRules实例方法中。)