ООП Python - отношения Класса

Принятие у меня есть система трех Классов. 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 из экземпляра PlayerClass?

  • Сделайте я должен передать ссылку на FieldClass экземпляр к PlayerClass?
  • Есть ли другой, лучший способ решить это? Выполнение вышеупомянутого сделало бы меня, должны включать дополнительную переменную в PlayerClass содержать FieldClass экземпляр.
  • Существует ли совершенно другой способ управлять отношениями класса в Python?
8
задан lamas 24 February 2010 в 17:35
поделиться

4 ответа

Я бы выбрал Dependency Injection: инстанцируйте GameClass с необходимыми FieldClass и 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 вы сможете легко получить доступ к необходимым членам после завершения фазы настройки.

6
ответ дан 5 December 2019 в 15:22
поделиться

Чтобы лучше понять отношения между классами, вы должны рассказать нам больше о своем проекте и о том, чего вы пытаетесь достичь.

Один из способов сослаться на экземпляр из FieldClass из PlayerClass в вашем примере - передать экземпляр GameClass в ] PlayerClass instance:

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)

Другой способ - передать переменную поля

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 , прежде чем приобретать дурные привычки.

4
ответ дан 5 December 2019 в 15:22
поделиться

Вы можете предоставить контекст дочерним объектам, то есть:

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)

Поскольку объекты знают свой контекст, они могут проникнуть в него и получить доступ к другим объектам в тот же контекст.

1
ответ дан 5 December 2019 в 15:22
поделиться

Я бы сделал что-то вроде следующего, где вы передаете 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)

С одной стороны, следует отметить, что сейчас хорошей практикой является наследование всех классов от объекта вместо того, чтобы они оставались изолированными.

0
ответ дан 5 December 2019 в 15:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: