Python:调用另一个类的方法的最佳方法?

问题描述:

我有以下代码:Python:调用另一个类的方法的最佳方法?

class Player: 
    def __init__(self, username, trip, model): 
     self.username = username 
     self.trip = trip 
     self.hp = 100 


    #### For player moving location/room #### 
    def Move(self, dest): 
     if dest == self.loc: 
      return True 

     # Check destination room is accessible from current room 
     for room in aGame['rooms']: 
      if room['ref'] == self.loc: 
       for acsroom in room['acs']: 
        if acsroom == dest: 
         self.loc = dest 
         return True 
     return False 

一个游戏是被这个类外定义因此,此代码不工作的阵列。 既然有可能成为这一类中的许多其他功能,这将有可能使用一个游戏阵列,我应该这样做:

class Player: 
    def __init__(self, username, trip, model, aGame): 
     self.username = username 
     self.trip = trip 
     self.hp = 100 
     self.aGame = aGame    

    #### For player moving location/room #### 
    def Move(self, dest): 
     if dest == self.loc: 
      return True 

     # Check destination room is accessible from current room 
     for room in self.aGame['rooms']: 
      if room['ref'] == self.loc: 
       for acsroom in room['acs']: 
        if acsroom == dest: 
         self.loc = dest 
         return True 
     return False 

或者它会更好地做到这一点:

class Player: 
    def __init__(self, username, trip, model): 
     self.username = username 
     self.trip = trip 
     self.hp = 100   

    #### For player moving location/room #### 
    def Move(self, dest, aGame): 
     if dest == self.loc: 
      return True 

     # Check destination room is accessible from current room 
     for room in aGame['rooms']: 
      if room['ref'] == self.loc: 
       for acsroom in room['acs']: 
        if acsroom == dest: 
         self.loc = dest 
         return True 
     return False 

或者我应该让aGame成为一个全局变量(如果是这样,请注意这个类在不同的文件中)?

由于aGame是一个遍布整个地方的数组,因此在每个类中都要复制它并不正确。 我可能有这个错误,我慢慢地学习OOP,所以谢谢你的帮助。

+3

实际上,您不会将aGame字典复制到每个类中,而是通过引用传递参数。 – miku 2011-01-27 03:27:38

在我看来,第一个选项是正确的,因为它没有很好的理由使用全局变量。所以选择在第二和第三之间。

决定功能是如果您打算要使用同一个Player实例来获得多个aGame值。如果只有一个值,那么我会将它传递给构造函数(您的选项2)或使用gnibbler的使其成为类变量的想法。我可能会倾向于将它传递给构造函数以便于测试。

如果您希望同一个Player实例可与多个aGame值一起使用,那么选项3可能是最简单的方法。

只有第一选择才有效。在第二个例子中,for room in self.aGame['rooms']将产生一个错误,因为无处游戏是绑定到自己的。它会工作,如果它是for room in aGame['rooms'],但那么你必须不必要地通过游戏每次你打电话move()

您也可以将其设为全局变量,但最好是让每个玩家都拥有一个aGame实例。如果您需要更改aGame并拥有多个玩家,则应将其定义为全局变量。

此外,只是挑剔,但aGame不是一个数组,它是一个字典。 Python语言甚至没有数组(尽管有些扩展可以)。

+0

对不起,我忘了删除'自我'。因为在第二个例子中,aGame变量被传入了方法。 – Tommo 2011-01-27 03:28:04

+0

如果我向Player类添加了一个游戏,是不是只是制作当前aGame的副本并将其应用到Player实例?所以如果aGame在课程初始化后发生变化,那么player1.aGame会有所不同? – Tommo 2011-01-27 03:30:44

+0

@Tommo,好的,那么我的答案仍然存在。为什么每次调用`move()`时都会传递`aGame``每个Player都可以拥有一个实例?第一种解决方案更有意义,并且需要较少的工作。如果您需要更改aGame并拥有多个玩家,则应将其定义为全局变量。 – 2011-01-27 03:31:09

是否aGame每个实例都一样? 然后你可以把它类属性要么喜欢这个

class Player: 
    aGame={'rooms':...} 
    ... 

Class Player: 
    ... 

Player.aGame={'rooms':...} 

在类中,你仍然可以通过self.aGame

访问我会使用上略有变化全球:

# in game.py or whatever 
class Game(object): 
    instance = {} # this is your aGame array 

# in player.py or whatever: 
from game import Game 

class Player(object): 
    # ... 
    def Move(self, dest): 
     # ... 
     for room in Game.instance['rooms']: 
      # ... 

或者,你可以让游戏成为一个适当的类,在初始化阶段将Game.instance = Game(...)分配给某处,并获得更多真正的单例模式。