Python面向对象编程 - 类之间的关系

8
假设我有一个由三个类组成的系统。 GameClass在初始化时创建其他两个类的实例。
class FieldClass:
    def __init__( self ):
        return
    def AnswerAQuestion( self ):    
        return 42

class PlayerClass:
    def __init__( self ):
        return
    def DoMagicHere( self ):
        # Access "AnswerAQuestion" located in the "FieldClass" instance in "GameClass"
        pass

class GameClass:
    def __init__( self ):
        self.Field = FieldClass()
        self.Player = PlayerClass()

如何从PlayerClass实例中访问位于FieldClass中的AnswerAQuestion()方法是最佳方式?

  • 我是否需要将对FieldClass实例的引用传递给PlayerClass
  • 是否有其他更好的解决方法?上述方法会使我不得不在PlayerClass中包含一个额外的变量来保存FieldClass实例。
  • 在Python中,是否有完全不同的管理类关系的方式?
4个回答

6

我建议使用依赖注入:在构造函数中实例化一个GameClass,并传入所需的FieldClassPlayerClass等依赖对象(即不再像当前代码中在GameClass内部创建依赖对象)。

class GameClass:
    def __init__( self, fc, pc ):
        self.Field = fc
        self.Player = pc

class PlayerClass:
    def __init__( self, fc ):
        self.fc = fc

    def DoMagicHere( self ):
        # use self.fc
        pass

fc=FieldClass()
pc=PlayerClass(fc)
gc=GameClass(fc, pc)

使用依赖注入,一旦设置阶段完成,您就可以轻松访问所需的成员。


4
为了更好地理解你的类关系,你需要告诉我们更多关于你的项目以及你想要实现的目标。
在你的示例中,引用“FieldClass”的“instance”从“PlayerClass”中一种方法是将“GameClass”实例传递给“PlayerClass”实例:
class PlayerClass:
    def __init__(self, game):
        self.game = game
    def DoMagicHere(self):
        self.game.Field.AnswerAQuestion()

# ...

class GameClass:
    def __init__( self ):
        self.Field = FieldClass()
        self.Player = PlayerClass(self)

另一种方法是通过传递field变量来实现。
class PlayerClass:
    def __init__(self, field):
        self.field = field
    def DoMagicHere(self):
        self.field.AnswerAQuestion()
# ...

class GameClass:
    def __init__( self ):
        self.Field = FieldClass()
        self.Player = PlayerClass(self.Field)

作为一个附注:您使用了一种奇特的命名方案。我建议使用以下方式:
 class Game:
     def __init__(self):
         self.field = Field()
         self.player = Player(...)

在养成不好的习惯之前,我建议您阅读Python风格指南


感谢您提供关于命名方案问题的信息。 - lamas

1
你可以为子对象提供上下文,例如:
class FieldClass:
  def __init__(self,game):
   self.game = game

class PlayerClass:
  def __init__(self,game):
    self.game = game
  def DoMagicHere(self):
    self.game.Field.AnswerAQuestion()

class GameClass:
  def __init__(self):
    self.Field = FieldClass(self)
    self.Player = PlayerClass(self)

由于对象知道它们的上下文,因此它们可以进入其中并访问同一上下文中的其他对象。

0
我会像下面这样做,你可以将Game作为后向引用传递进来,从而让你可以访问其他相关的类。通过这种方式,你可以选择性地给那个玩家实例一个直接关联到该领域的关系。
class FieldClass(object):
    def __init__(self, game):
        self.Game = game
    def AnswerAQuestion(self):    
        return 42

class PlayerClass(object):
    def __init__(self, game):
        self.Game = game
        self.Field = game.Field # Optional
    def DoMagicHere(self):
        self.Game.Field.AnswerAQuestion()
        self.Field.AnswerAQuestion() # Optional

class GameClass(object):
    def __init__(self):
        self.Field = FieldClass(self)
        self.Player = PlayerClass(self)

一个小提示是,现在最好的做法是让你的所有类都继承自object,而不是让它们独立存在。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接