Принятие у меня есть система трех Классов. 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
экземпляр.Я бы выбрал 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 вы сможете легко получить доступ к необходимым членам после завершения фазы настройки.
Чтобы лучше понять отношения между классами, вы должны рассказать нам больше о своем проекте и о том, чего вы пытаетесь достичь.
Один из способов сослаться на экземпляр из 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 , прежде чем приобретать дурные привычки.
Вы можете предоставить контекст дочерним объектам, то есть:
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)
Поскольку объекты знают свой контекст, они могут проникнуть в него и получить доступ к другим объектам в тот же контекст.
Я бы сделал что-то вроде следующего, где вы передаете 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)
С одной стороны, следует отметить, что сейчас хорошей практикой является наследование всех классов от объекта
вместо того, чтобы они оставались изолированными.