Python OOP - 类关系

时间:2010-02-24 17:35:30

标签: python oop

假设我有一个由三个类组成的系统。 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()

AnswerAQuestion()的实例中访问位于FieldClass的{​​{1}}的最佳方法是什么?

  • 我是否必须将PlayerClass实例的引用传递给FieldClass
  • 还有另一种更好的解决方法吗?执行上述操作会使我必须在PlayerClass中添加一个额外的变量来保存PlayerClass实例。
  • 在Python中管理类关系是否存在完全不同的方式?

4 个答案:

答案 0 :(得分:6)

我会选择Dependency Injection:在构造函数调用等中使用所需的GameClassFieldClass实例化PlayerClass(即不是从内部创建依赖对象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)

使用DI,您可以在设置阶段完成后轻松访问所需的成员。

答案 1 :(得分:4)

为了更好地了解您的课堂关系,您必须告诉我们有关您的项目以及您要完成的内容的更多信息。

在您的示例中从FieldClass引用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 Style Guide

答案 2 :(得分: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)

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

答案 3 :(得分:0)

我会做类似以下的事情,你将Game in作为反向引用传递,允许你访问其他相关的类。通过这种方式,您可以选择为该播放器实例提供与该字段的直接关系。

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,而不是让他们独自站立。